]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManager.c
268dfab469992b0470d86e8a49ed0b2177e9b42b
[mirror_edk2.git] / SecurityPkg / UserIdentification / UserIdentifyManagerDxe / UserIdentifyManager.c
1 /** @file
2 This driver manages user information and produces user manager protocol.
3
4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "UserIdentifyManager.h"
16
17 //
18 // Default user name.
19 //
20 CHAR16 mUserName[] = L"Administrator";
21
22 //
23 // Points to the user profile database.
24 //
25 USER_PROFILE_DB *mUserProfileDb = NULL;
26
27 //
28 // Points to the credential providers found in system.
29 //
30 CREDENTIAL_PROVIDER_INFO *mProviderDb = NULL;
31
32 //
33 // Current user shared in multi function.
34 //
35 EFI_USER_PROFILE_HANDLE mCurrentUser = NULL;
36
37 //
38 // Flag indicates a user is identified.
39 //
40 BOOLEAN mIdentified = FALSE;
41 USER_MANAGER_CALLBACK_INFO *mCallbackInfo = NULL;
42 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
43 {
44 {
45 HARDWARE_DEVICE_PATH,
46 HW_VENDOR_DP,
47 {
48 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
49 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
50 }
51 },
52 USER_IDENTIFY_MANAGER_GUID
53 },
54 {
55 END_DEVICE_PATH_TYPE,
56 END_ENTIRE_DEVICE_PATH_SUBTYPE,
57 {
58 (UINT8) (END_DEVICE_PATH_LENGTH),
59 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
60 }
61 }
62 };
63
64
65 EFI_USER_MANAGER_PROTOCOL gUserIdentifyManager = {
66 UserProfileCreate,
67 UserProfileDelete,
68 UserProfileGetNext,
69 UserProfileCurrent,
70 UserProfileIdentify,
71 UserProfileFind,
72 UserProfileNotify,
73 UserProfileGetInfo,
74 UserProfileSetInfo,
75 UserProfileDeleteInfo,
76 UserProfileGetNextInfo,
77 };
78
79
80 /**
81 Find the specified user in the user database.
82
83 This function searches the specified user from the beginning of the user database.
84 And if NextUser is TRUE, return the next User in the user database.
85
86 @param[in, out] User On entry, points to the user profile entry to search.
87 On return, points to the user profile entry or NULL if not found.
88 @param[in] NextUser If FALSE, find the user in user profile database specifyed by User
89 If TRUE, find the next user in user profile database specifyed
90 by User.
91 @param[out] ProfileIndex A pointer to the index of user profile database that matches the
92 user specifyed by User.
93
94 @retval EFI_NOT_FOUND User was NULL, or User was not found, or the next user was not found.
95 @retval EFI_SUCCESS User or the next user are found in user profile database
96
97 **/
98 EFI_STATUS
99 FindUserProfile (
100 IN OUT USER_PROFILE_ENTRY **User,
101 IN BOOLEAN NextUser,
102 OUT UINTN *ProfileIndex OPTIONAL
103 )
104 {
105 UINTN Index;
106
107 //
108 // Check parameters
109 //
110 if ((mUserProfileDb == NULL) || (User == NULL)) {
111 return EFI_NOT_FOUND;
112 }
113
114 //
115 // Check whether the user profile is in the user profile database.
116 //
117 for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {
118 if (mUserProfileDb->UserProfile[Index] == *User) {
119 if (ProfileIndex != NULL) {
120 *ProfileIndex = Index;
121 }
122 break;
123 }
124 }
125
126 if (NextUser) {
127 //
128 // Find the next user profile.
129 //
130 Index++;
131 if (Index < mUserProfileDb->UserProfileNum) {
132 *User = mUserProfileDb->UserProfile[Index];
133 } else if (Index == mUserProfileDb->UserProfileNum) {
134 *User = NULL;
135 return EFI_NOT_FOUND;
136 } else {
137 if ((mUserProfileDb->UserProfileNum > 0) && (*User == NULL)) {
138 *User = mUserProfileDb->UserProfile[0];
139 } else {
140 *User = NULL;
141 return EFI_NOT_FOUND;
142 }
143 }
144 } else if (Index == mUserProfileDb->UserProfileNum) {
145 return EFI_NOT_FOUND;
146 }
147
148 return EFI_SUCCESS;
149 }
150
151 /**
152 Find the specified user information record in the specified User profile.
153
154 This function searches the specified user information record from the beginning of the user
155 profile. And if NextInfo is TRUE, return the next info in the user profile.
156
157 @param[in] User Points to the user profile entry.
158 @param[in, out] Info On entry, points to the user information record or NULL to start
159 searching with the first user information record.
160 On return, points to the user information record or NULL if not found.
161 @param[in] NextInfo If FALSE, find the user information record in profile specifyed by User.
162 If TRUE, find the next user information record in profile specifyed
163 by User.
164 @param[out] Offset A pointer to the offset of the information record in the user profile.
165
166 @retval EFI_INVALID_PARAMETER Info is NULL
167 @retval EFI_NOT_FOUND Info was not found, or the next Info was not found.
168 @retval EFI_SUCCESS Info or the next info are found in user profile.
169
170 **/
171 EFI_STATUS
172 FindUserInfo (
173 IN USER_PROFILE_ENTRY * User,
174 IN OUT EFI_USER_INFO **Info,
175 IN BOOLEAN NextInfo,
176 OUT UINTN *Offset OPTIONAL
177 )
178 {
179 EFI_STATUS Status;
180 EFI_USER_INFO *UserInfo;
181 UINTN InfoLen;
182
183 if (Info == NULL) {
184 return EFI_INVALID_PARAMETER;
185 }
186
187 //
188 // Check user profile entry
189 //
190 Status = FindUserProfile (&User, FALSE, NULL);
191 if (EFI_ERROR (Status)) {
192 return Status;
193 }
194
195 //
196 // Find user information in the specified user record.
197 //
198 InfoLen = 0;
199 while (InfoLen < User->UserProfileSize) {
200 UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);
201 if (UserInfo == *Info) {
202 if (Offset != NULL) {
203 *Offset = InfoLen;
204 }
205 break;
206 }
207 InfoLen += ALIGN_VARIABLE (UserInfo->InfoSize);
208 }
209
210 //
211 // Check whether to find the next user information.
212 //
213 if (NextInfo) {
214 if (InfoLen < User->UserProfileSize) {
215 UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);
216 InfoLen += ALIGN_VARIABLE (UserInfo->InfoSize);
217 if (InfoLen < User->UserProfileSize) {
218 *Info = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);
219 if (Offset != NULL) {
220 *Offset = InfoLen;
221 }
222 } else if (InfoLen == User->UserProfileSize) {
223 *Info = NULL;
224 return EFI_NOT_FOUND;
225 }
226 } else {
227 if (*Info == NULL) {
228 *Info = (EFI_USER_INFO *) User->ProfileInfo;
229 if (Offset != NULL) {
230 *Offset = 0;
231 }
232 } else {
233 *Info = NULL;
234 return EFI_NOT_FOUND;
235 }
236 }
237 } else if (InfoLen == User->UserProfileSize) {
238 return EFI_NOT_FOUND;
239 }
240
241 return EFI_SUCCESS;
242 }
243
244 /**
245 Find a user infomation record by the information record type.
246
247 This function searches all user information records of User. The search starts with the
248 user information record following Info and continues until either the information is found
249 or there are no more user infomation record.
250 A match occurs when a Info.InfoType field matches the user information record type.
251
252 @param[in] User Points to the user profile record to search.
253 @param[in, out] Info On entry, points to the user information record or NULL to start
254 searching with the first user information record.
255 On return, points to the user information record or NULL if not found.
256 @param[in] InfoType The infomation type to be searched.
257
258 @retval EFI_SUCCESS User information was found. Info points to the user information record.
259 @retval EFI_NOT_FOUND User information was not found.
260 @retval EFI_INVALID_PARAMETER User is NULL or Info is NULL.
261
262 **/
263 EFI_STATUS
264 FindUserInfoByType (
265 IN USER_PROFILE_ENTRY *User,
266 IN OUT EFI_USER_INFO **Info,
267 IN UINT8 InfoType
268 )
269 {
270 EFI_STATUS Status;
271 EFI_USER_INFO *UserInfo;
272 UINTN InfoLen;
273
274 if (Info == NULL) {
275 return EFI_INVALID_PARAMETER;
276 }
277
278 //
279 // Check whether the user has the specified user information.
280 //
281 InfoLen = 0;
282 if (*Info == NULL) {
283 Status = FindUserProfile (&User, FALSE, NULL);
284 } else {
285 Status = FindUserInfo (User, Info, TRUE, &InfoLen);
286 }
287
288 if (EFI_ERROR (Status)) {
289 return EFI_NOT_FOUND;
290 }
291
292 while (InfoLen < User->UserProfileSize) {
293 UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + InfoLen);
294 if (UserInfo->InfoType == InfoType) {
295 if (UserInfo != *Info) {
296 *Info = UserInfo;
297 return EFI_SUCCESS;
298 }
299 }
300
301 InfoLen += ALIGN_VARIABLE (UserInfo->InfoSize);
302 }
303
304 *Info = NULL;
305 return EFI_NOT_FOUND;
306 }
307
308 /**
309 Find a user using a user information record.
310
311 This function searches all user profiles for the specified user information record. The
312 search starts with the user information record handle following UserInfo and continues
313 until either the information is found or there are no more user profiles.
314 A match occurs when the Info.InfoType field matches the user information record type and the
315 user information record data matches the portion of Info passed the EFI_USER_INFO header.
316
317 @param[in, out] User On entry, points to the previously returned user profile record,
318 or NULL to start searching with the first user profile.
319 On return, points to the user profile entry, or NULL if not found.
320 @param[in, out] UserInfo On entry, points to the previously returned user information record,
321 or NULL to start searching with the first.
322 On return, points to the user information record, or NULL if not found.
323 @param[in] Info Points to the buffer containing the user information to be compared
324 to the user information record.
325 @param[in] InfoSize The size of Info, in bytes. Same as Info->InfoSize.
326
327 @retval EFI_SUCCESS User information was found. User points to the user profile record,
328 and UserInfo points to the user information record.
329 @retval EFI_NOT_FOUND User information was not found.
330 @retval EFI_INVALID_PARAMETER User is NULL; Info is NULL; or, InfoSize is too small.
331
332 **/
333 EFI_STATUS
334 FindUserProfileByInfo (
335 IN OUT USER_PROFILE_ENTRY **User,
336 IN OUT EFI_USER_INFO **UserInfo, OPTIONAL
337 IN EFI_USER_INFO *Info,
338 IN UINTN InfoSize
339 )
340 {
341 EFI_STATUS Status;
342 EFI_USER_INFO *InfoEntry;
343
344
345 if ((User == NULL) || (Info == NULL)) {
346 return EFI_INVALID_PARAMETER;
347 }
348
349 if (InfoSize < sizeof (EFI_USER_INFO)) {
350 return EFI_INVALID_PARAMETER;
351 }
352
353 if (UserInfo != NULL) {
354 InfoEntry = *UserInfo;
355 } else {
356 InfoEntry = NULL;
357 }
358 //
359 // Find user profile according to information.
360 //
361 if (*User == NULL) {
362 *User = mUserProfileDb->UserProfile[0];
363 }
364
365 //
366 // Check user profile handle.
367 //
368 Status = FindUserProfile (User, FALSE, NULL);
369
370 while (!EFI_ERROR (Status)) {
371 //
372 // Find the user information in a user profile.
373 //
374 while (TRUE) {
375 Status = FindUserInfoByType (*User, &InfoEntry, Info->InfoType);
376 if (EFI_ERROR (Status)) {
377 break;
378 }
379
380 if (InfoSize == Info->InfoSize) {
381 if (CompareMem ((UINT8 *) (InfoEntry + 1), (UINT8 *) (Info + 1), InfoSize - sizeof (EFI_USER_INFO)) == 0) {
382 //
383 // Found the infomation record.
384 //
385 if (UserInfo != NULL) {
386 *UserInfo = InfoEntry;
387 }
388 return EFI_SUCCESS;
389 }
390 }
391 }
392
393 //
394 // Get next user profile.
395 //
396 InfoEntry = NULL;
397 Status = FindUserProfile (User, TRUE, NULL);
398 }
399
400 return EFI_NOT_FOUND;
401 }
402
403
404 /**
405 Check whether the access policy is valid.
406
407 @param[in] PolicyInfo Point to the access policy.
408 @param[in] InfoLen The policy length.
409
410 @retval TRUE The policy is a valid access policy.
411 @retval FALSE The access policy is not a valid access policy.
412
413 **/
414 BOOLEAN
415 CheckAccessPolicy (
416 IN UINT8 *PolicyInfo,
417 IN UINTN InfoLen
418 )
419 {
420 UINTN TotalLen;
421 UINTN ValueLen;
422 UINTN OffSet;
423 EFI_USER_INFO_ACCESS_CONTROL Access;
424 EFI_DEVICE_PATH_PROTOCOL *Path;
425 UINTN PathSize;
426
427 TotalLen = 0;
428 while (TotalLen < InfoLen) {
429 //
430 // Check access policy according to type.
431 //
432 CopyMem (&Access, PolicyInfo + TotalLen, sizeof (Access));
433 ValueLen = Access.Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL);
434 switch (Access.Type) {
435 case EFI_USER_INFO_ACCESS_FORBID_LOAD:
436 case EFI_USER_INFO_ACCESS_PERMIT_LOAD:
437 case EFI_USER_INFO_ACCESS_FORBID_CONNECT:
438 case EFI_USER_INFO_ACCESS_PERMIT_CONNECT:
439 OffSet = 0;
440 while (OffSet < ValueLen) {
441 Path = (EFI_DEVICE_PATH_PROTOCOL *) (PolicyInfo + TotalLen + sizeof (Access) + OffSet);
442 PathSize = GetDevicePathSize (Path);
443 OffSet += PathSize;
444 }
445 if (OffSet != ValueLen) {
446 return FALSE;
447 }
448 break;
449
450 case EFI_USER_INFO_ACCESS_SETUP:
451 if (ValueLen % sizeof (EFI_GUID) != 0) {
452 return FALSE;
453 }
454 break;
455
456 case EFI_USER_INFO_ACCESS_BOOT_ORDER:
457 if (ValueLen % sizeof (EFI_USER_INFO_ACCESS_BOOT_ORDER_HDR) != 0) {
458 return FALSE;
459 }
460 break;
461
462 case EFI_USER_INFO_ACCESS_ENROLL_SELF:
463 case EFI_USER_INFO_ACCESS_ENROLL_OTHERS:
464 case EFI_USER_INFO_ACCESS_MANAGE:
465 if (ValueLen != 0) {
466 return FALSE;
467 }
468 break;
469
470 default:
471 return FALSE;
472 break;
473 }
474
475 TotalLen += Access.Size;
476 }
477
478 if (TotalLen != InfoLen) {
479 return FALSE;
480 }
481
482 return TRUE;
483 }
484
485
486 /**
487 Check whether the identity policy is valid.
488
489 @param[in] PolicyInfo Point to the identity policy.
490 @param[in] InfoLen The policy length.
491
492 @retval TRUE The policy is a valid identity policy.
493 @retval FALSE The access policy is not a valid identity policy.
494
495 **/
496 BOOLEAN
497 CheckIdentityPolicy (
498 IN UINT8 *PolicyInfo,
499 IN UINTN InfoLen
500 )
501 {
502 UINTN TotalLen;
503 UINTN ValueLen;
504 EFI_USER_INFO_IDENTITY_POLICY *Identity;
505
506 TotalLen = 0;
507
508 //
509 // Check each part of policy expression.
510 //
511 while (TotalLen < InfoLen) {
512 //
513 // Check access polisy according to type.
514 //
515 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (PolicyInfo + TotalLen);
516 ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);
517 switch (Identity->Type) {
518 //
519 // Check False option.
520 //
521 case EFI_USER_INFO_IDENTITY_FALSE:
522 if (ValueLen != 0) {
523 return FALSE;
524 }
525 break;
526
527 //
528 // Check True option.
529 //
530 case EFI_USER_INFO_IDENTITY_TRUE:
531 if (ValueLen != 0) {
532 return FALSE;
533 }
534 break;
535
536 //
537 // Check negative operation.
538 //
539 case EFI_USER_INFO_IDENTITY_NOT:
540 if (ValueLen != 0) {
541 return FALSE;
542 }
543 break;
544
545 //
546 // Check and operation.
547 //
548 case EFI_USER_INFO_IDENTITY_AND:
549 if (ValueLen != 0) {
550 return FALSE;
551 }
552 break;
553
554 //
555 // Check or operation.
556 //
557 case EFI_USER_INFO_IDENTITY_OR:
558 if (ValueLen != 0) {
559 return FALSE;
560 }
561 break;
562
563 //
564 // Check credential provider by type.
565 //
566 case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:
567 if (ValueLen != sizeof (EFI_GUID)) {
568 return FALSE;
569 }
570 break;
571
572 //
573 // Check credential provider by ID.
574 //
575 case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:
576 if (ValueLen != sizeof (EFI_GUID)) {
577 return FALSE;
578 }
579 break;
580
581 default:
582 return FALSE;
583 break;
584 }
585
586 TotalLen += Identity->Length;
587 }
588
589 if (TotalLen != InfoLen) {
590 return FALSE;
591 }
592
593 return TRUE;
594 }
595
596
597 /**
598 Check whether the user information is a valid user information record.
599
600 @param[in] Info points to the user information.
601
602 @retval TRUE The info is a valid user information record.
603 @retval FALSE The info is not a valid user information record.
604
605 **/
606 BOOLEAN
607 CheckUserInfo (
608 IN CONST EFI_USER_INFO *Info
609 )
610 {
611 UINTN InfoLen;
612
613 if (Info == NULL) {
614 return FALSE;
615 }
616 //
617 // Check user information according to information type.
618 //
619 InfoLen = Info->InfoSize - sizeof (EFI_USER_INFO);
620 switch (Info->InfoType) {
621 case EFI_USER_INFO_EMPTY_RECORD:
622 if (InfoLen != 0) {
623 return FALSE;
624 }
625 break;
626
627 case EFI_USER_INFO_NAME_RECORD:
628 case EFI_USER_INFO_CREDENTIAL_TYPE_NAME_RECORD:
629 case EFI_USER_INFO_CREDENTIAL_PROVIDER_NAME_RECORD:
630 break;
631
632 case EFI_USER_INFO_CREATE_DATE_RECORD:
633 case EFI_USER_INFO_USAGE_DATE_RECORD:
634 if (InfoLen != sizeof (EFI_TIME)) {
635 return FALSE;
636 }
637 break;
638
639 case EFI_USER_INFO_USAGE_COUNT_RECORD:
640 if (InfoLen != sizeof (UINT64)) {
641 return FALSE;
642 }
643 break;
644
645 case EFI_USER_INFO_IDENTIFIER_RECORD:
646 if (InfoLen != 16) {
647 return FALSE;
648 }
649 break;
650
651 case EFI_USER_INFO_CREDENTIAL_TYPE_RECORD:
652 case EFI_USER_INFO_CREDENTIAL_PROVIDER_RECORD:
653 case EFI_USER_INFO_GUID_RECORD:
654 if (InfoLen != sizeof (EFI_GUID)) {
655 return FALSE;
656 }
657 break;
658
659 case EFI_USER_INFO_PKCS11_RECORD:
660 case EFI_USER_INFO_CBEFF_RECORD:
661 break;
662
663 case EFI_USER_INFO_FAR_RECORD:
664 case EFI_USER_INFO_RETRY_RECORD:
665 if (InfoLen != 1) {
666 return FALSE;
667 }
668 break;
669
670 case EFI_USER_INFO_ACCESS_POLICY_RECORD:
671 if(!CheckAccessPolicy ((UINT8 *) (Info + 1), InfoLen)) {
672 return FALSE;
673 }
674 break;
675
676 case EFI_USER_INFO_IDENTITY_POLICY_RECORD:
677 if (!CheckIdentityPolicy ((UINT8 *) (Info + 1), InfoLen)) {
678 return FALSE;
679 }
680 break;
681
682 default:
683 return FALSE;
684 break;
685 }
686
687 return TRUE;
688 }
689
690
691 /**
692 Check the user profile data format to be added.
693
694 @param[in] UserProfileInfo Points to the user profile data.
695 @param[in] UserProfileSize The length of user profile data.
696
697 @retval TRUE It is a valid user profile.
698 @retval FALSE It is not a valid user profile.
699
700 **/
701 BOOLEAN
702 CheckProfileInfo (
703 IN UINT8 *UserProfileInfo,
704 IN UINTN UserProfileSize
705 )
706 {
707 UINTN ChkLen;
708 EFI_USER_INFO *Info;
709
710 if (UserProfileInfo == NULL) {
711 return FALSE;
712 }
713
714 //
715 // Check user profile information length.
716 //
717 ChkLen = 0;
718 while (ChkLen < UserProfileSize) {
719 Info = (EFI_USER_INFO *) (UserProfileInfo + ChkLen);
720 //
721 // Check user information format.
722 //
723 if (!CheckUserInfo (Info)) {
724 return FALSE;
725 }
726
727 ChkLen += ALIGN_VARIABLE (Info->InfoSize);
728 }
729
730 if (ChkLen != UserProfileSize) {
731 return FALSE;
732 }
733
734 return TRUE;
735 }
736
737
738 /**
739 Find the specified RightType in current user profile.
740
741 @param[in] RightType Could be EFI_USER_INFO_ACCESS_MANAGE,
742 EFI_USER_INFO_ACCESS_ENROLL_OTHERS or
743 EFI_USER_INFO_ACCESS_ENROLL_SELF.
744
745 @retval TRUE Find the specified RightType in current user profile.
746 @retval FALSE Can't find the right in the profile.
747
748 **/
749 BOOLEAN
750 CheckCurrentUserAccessRight (
751 IN UINT32 RightType
752 )
753 {
754 EFI_STATUS Status;
755 EFI_USER_INFO *Info;
756 UINTN TotalLen;
757 UINTN CheckLen;
758 EFI_USER_INFO_ACCESS_CONTROL Access;
759
760 //
761 // Get user access right information.
762 //
763 Info = NULL;
764 Status = FindUserInfoByType (
765 (USER_PROFILE_ENTRY *) mCurrentUser,
766 &Info,
767 EFI_USER_INFO_ACCESS_POLICY_RECORD
768 );
769 if (EFI_ERROR (Status)) {
770 return FALSE;
771 }
772
773 ASSERT (Info != NULL);
774 TotalLen = Info->InfoSize - sizeof (EFI_USER_INFO);
775 CheckLen = 0;
776 while (CheckLen < TotalLen) {
777 //
778 // Check right according to access type.
779 //
780 CopyMem (&Access, (UINT8 *) (Info + 1) + CheckLen, sizeof (Access));
781 if (Access.Type == RightType) {
782 return TRUE;;
783 }
784
785 CheckLen += Access.Size;
786 }
787
788 return FALSE;
789 }
790
791
792 /**
793 Create a unique user identifier.
794
795 @param[out] Identifier This points to the identifier.
796
797 **/
798 VOID
799 GenerateIdentifier (
800 OUT UINT8 *Identifier
801 )
802 {
803 EFI_TIME Time;
804 UINT64 MonotonicCount;
805 UINT32 *MonotonicPointer;
806 UINTN Index;
807
808 //
809 // Create a unique user identifier.
810 //
811 gRT->GetTime (&Time, NULL);
812 CopyMem (Identifier, &Time, sizeof (EFI_TIME));
813 //
814 // Remove zeros.
815 //
816 for (Index = 0; Index < sizeof (EFI_TIME); Index++) {
817 if (Identifier[Index] == 0) {
818 Identifier[Index] = 0x5a;
819 }
820 }
821
822 MonotonicPointer = (UINT32 *) Identifier;
823 gBS->GetNextMonotonicCount (&MonotonicCount);
824 MonotonicPointer[0] += (UINT32) MonotonicCount;
825 MonotonicPointer[1] += (UINT32) MonotonicCount;
826 MonotonicPointer[2] += (UINT32) MonotonicCount;
827 MonotonicPointer[3] += (UINT32) MonotonicCount;
828 }
829
830
831 /**
832 Generate unique user ID.
833
834 @param[out] UserId Points to the user identifer.
835
836 **/
837 VOID
838 GenerateUserId (
839 OUT UINT8 *UserId
840 )
841 {
842 EFI_STATUS Status;
843 USER_PROFILE_ENTRY *UserProfile;
844 EFI_USER_INFO *UserInfo;
845 UINTN Index;
846
847 //
848 // Generate unique user ID
849 //
850 while (TRUE) {
851 GenerateIdentifier (UserId);
852 //
853 // Check whether it's unique in user profile database.
854 //
855 if (mUserProfileDb == NULL) {
856 return ;
857 }
858
859 for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {
860 UserProfile = (USER_PROFILE_ENTRY *) (mUserProfileDb->UserProfile[Index]);
861 UserInfo = NULL;
862 Status = FindUserInfoByType (UserProfile, &UserInfo, EFI_USER_INFO_IDENTIFIER_RECORD);
863 if (EFI_ERROR (Status)) {
864 continue;
865 }
866
867 if (CompareMem ((UINT8 *) (UserInfo + 1), UserId, sizeof (EFI_USER_INFO_IDENTIFIER)) == 0) {
868 break;
869 }
870 }
871
872 if (Index == mUserProfileDb->UserProfileNum) {
873 return ;
874 }
875 }
876 }
877
878
879 /**
880 Expand user profile database.
881
882 @retval TRUE Success to expand user profile database.
883 @retval FALSE Fail to expand user profile database.
884
885 **/
886 BOOLEAN
887 ExpandUsermUserProfileDb (
888 VOID
889 )
890 {
891 UINTN MaxNum;
892 USER_PROFILE_DB *NewDataBase;
893
894 //
895 // Create new user profile database.
896 //
897 if (mUserProfileDb == NULL) {
898 MaxNum = USER_NUMBER_INC;
899 } else {
900 MaxNum = mUserProfileDb->MaxProfileNum + USER_NUMBER_INC;
901 }
902
903 NewDataBase = AllocateZeroPool (
904 sizeof (USER_PROFILE_DB) - sizeof (EFI_USER_PROFILE_HANDLE) +
905 MaxNum * sizeof (EFI_USER_PROFILE_HANDLE)
906 );
907 if (NewDataBase == NULL) {
908 return FALSE;
909 }
910
911 NewDataBase->MaxProfileNum = MaxNum;
912
913 //
914 // Copy old user profile database value
915 //
916 if (mUserProfileDb == NULL) {
917 NewDataBase->UserProfileNum = 0;
918 } else {
919 NewDataBase->UserProfileNum = mUserProfileDb->UserProfileNum;
920 CopyMem (
921 NewDataBase->UserProfile,
922 mUserProfileDb->UserProfile,
923 NewDataBase->UserProfileNum * sizeof (EFI_USER_PROFILE_HANDLE)
924 );
925 FreePool (mUserProfileDb);
926 }
927
928 mUserProfileDb = NewDataBase;
929 return TRUE;
930 }
931
932
933 /**
934 Expand user profile
935
936 @param[in] User Points to user profile.
937 @param[in] ExpandSize The size of user profile.
938
939 @retval TRUE Success to expand user profile size.
940 @retval FALSE Fail to expand user profile size.
941
942 **/
943 BOOLEAN
944 ExpandUserProfile (
945 IN USER_PROFILE_ENTRY *User,
946 IN UINTN ExpandSize
947 )
948 {
949 UINT8 *Info;
950 UINTN InfoSizeInc;
951
952 //
953 // Allocate new memory.
954 //
955 InfoSizeInc = 128;
956 User->MaxProfileSize += ((ExpandSize + InfoSizeInc - 1) / InfoSizeInc) * InfoSizeInc;
957 Info = AllocateZeroPool (User->MaxProfileSize);
958 if (Info == NULL) {
959 return FALSE;
960 }
961
962 //
963 // Copy exist information.
964 //
965 if (User->UserProfileSize > 0) {
966 CopyMem (Info, User->ProfileInfo, User->UserProfileSize);
967 FreePool (User->ProfileInfo);
968 }
969
970 User->ProfileInfo = Info;
971 return TRUE;
972 }
973
974
975 /**
976 Save the user profile to non-volatile memory, or delete it from non-volatile memory.
977
978 @param[in] User Point to the user profile
979 @param[in] Delete If TRUE, delete the found user profile.
980 If FALSE, save the user profile.
981 @retval EFI_SUCCESS Save or delete user profile successfully.
982 @retval Others Fail to change the profile.
983
984 **/
985 EFI_STATUS
986 SaveNvUserProfile (
987 IN USER_PROFILE_ENTRY *User,
988 IN BOOLEAN Delete
989 )
990 {
991 EFI_STATUS Status;
992
993 //
994 // Check user profile entry.
995 //
996 Status = FindUserProfile (&User, FALSE, NULL);
997 if (EFI_ERROR (Status)) {
998 return Status;
999 }
1000
1001 //
1002 // Save the user profile to non-volatile memory.
1003 //
1004 Status = gRT->SetVariable (
1005 User->UserVarName,
1006 &gUserIdentifyManagerGuid,
1007 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1008 Delete ? 0 : User->UserProfileSize,
1009 User->ProfileInfo
1010 );
1011 return Status;
1012 }
1013
1014 /**
1015 Add one new user info into the user's profile.
1016
1017 @param[in] User point to the user profile
1018 @param[in] Info Points to the user information payload.
1019 @param[in] InfoSize The size of the user information payload, in bytes.
1020 @param[out] UserInfo Point to the new info in user profile
1021 @param[in] Save If TRUE, save the profile to NV flash.
1022 If FALSE, don't need to save the profile to NV flash.
1023
1024 @retval EFI_SUCCESS Add user info to user profile successfully.
1025 @retval Others Fail to add user info to user profile.
1026
1027 **/
1028 EFI_STATUS
1029 AddUserInfo (
1030 IN USER_PROFILE_ENTRY *User,
1031 IN UINT8 *Info,
1032 IN UINTN InfoSize,
1033 OUT EFI_USER_INFO **UserInfo, OPTIONAL
1034 IN BOOLEAN Save
1035 )
1036 {
1037 EFI_STATUS Status;
1038
1039 if ((Info == NULL) || (User == NULL)) {
1040 return EFI_INVALID_PARAMETER;
1041 }
1042
1043 //
1044 // Check user profile handle.
1045 //
1046 Status = FindUserProfile (&User, FALSE, NULL);
1047 if (EFI_ERROR (Status)) {
1048 return Status;
1049 }
1050
1051 //
1052 // Check user information memory size.
1053 //
1054 if (User->MaxProfileSize - User->UserProfileSize < ALIGN_VARIABLE (InfoSize)) {
1055 if (!ExpandUserProfile (User, ALIGN_VARIABLE (InfoSize))) {
1056 return EFI_OUT_OF_RESOURCES;
1057 }
1058 }
1059
1060 //
1061 // Add new user information.
1062 //
1063 CopyMem (User->ProfileInfo + User->UserProfileSize, Info, InfoSize);
1064 if (UserInfo != NULL) {
1065 *UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + User->UserProfileSize);
1066 }
1067 User->UserProfileSize += ALIGN_VARIABLE (InfoSize);
1068
1069 //
1070 // Save user profile information.
1071 //
1072 if (Save) {
1073 Status = SaveNvUserProfile (User, FALSE);
1074 }
1075
1076 return Status;
1077 }
1078
1079
1080 /**
1081 Get the user info from the specified user info handle.
1082
1083 @param[in] User Point to the user profile.
1084 @param[in] UserInfo Point to the user information record to get.
1085 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes.
1086 On exit, holds the user information.
1087 @param[in, out] InfoSize On entry, points to the size of Info.
1088 On return, points to the size of the user information.
1089 @param[in] ChkRight If TRUE, check the user info attribute.
1090 If FALSE, don't check the user info attribute.
1091
1092
1093 @retval EFI_ACCESS_DENIED The information cannot be accessed by the current user.
1094 @retval EFI_INVALID_PARAMETER InfoSize is NULL or UserInfo is NULL.
1095 @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the
1096 returned data. The actual size required is returned in *InfoSize.
1097 @retval EFI_SUCCESS Information returned successfully.
1098
1099 **/
1100 EFI_STATUS
1101 GetUserInfo (
1102 IN USER_PROFILE_ENTRY *User,
1103 IN EFI_USER_INFO *UserInfo,
1104 OUT EFI_USER_INFO *Info,
1105 IN OUT UINTN *InfoSize,
1106 IN BOOLEAN ChkRight
1107 )
1108 {
1109 EFI_STATUS Status;
1110
1111 if ((InfoSize == NULL) || (UserInfo == NULL)) {
1112 return EFI_INVALID_PARAMETER;
1113 }
1114
1115 if ((*InfoSize != 0) && (Info == NULL)) {
1116 return EFI_INVALID_PARAMETER;
1117 }
1118
1119 //
1120 // Find the user information to get.
1121 //
1122 Status = FindUserInfo (User, &UserInfo, FALSE, NULL);
1123 if (EFI_ERROR (Status)) {
1124 return Status;
1125 }
1126
1127 //
1128 // Check information attributes.
1129 //
1130 if (ChkRight) {
1131 switch (UserInfo->InfoAttribs & EFI_USER_INFO_ACCESS) {
1132 case EFI_USER_INFO_PRIVATE:
1133 case EFI_USER_INFO_PROTECTED:
1134 if (User != mCurrentUser) {
1135 return EFI_ACCESS_DENIED;
1136 }
1137 break;
1138
1139 case EFI_USER_INFO_PUBLIC:
1140 break;
1141
1142 default:
1143 return EFI_INVALID_PARAMETER;
1144 break;
1145 }
1146 }
1147
1148 //
1149 // Get user information.
1150 //
1151 if (UserInfo->InfoSize > *InfoSize) {
1152 *InfoSize = UserInfo->InfoSize;
1153 return EFI_BUFFER_TOO_SMALL;
1154 }
1155
1156 *InfoSize = UserInfo->InfoSize;
1157 if (Info != NULL) {
1158 CopyMem (Info, UserInfo, *InfoSize);
1159 }
1160
1161 return EFI_SUCCESS;
1162 }
1163
1164
1165 /**
1166 Delete the specified user information from user profile.
1167
1168 @param[in] User Point to the user profile.
1169 @param[in] Info Point to the user information record to delete.
1170 @param[in] Save If TRUE, save the profile to NV flash.
1171 If FALSE, don't need to save the profile to NV flash.
1172
1173 @retval EFI_SUCCESS Delete user info from user profile successfully.
1174 @retval Others Fail to delete user info from user profile.
1175
1176 **/
1177 EFI_STATUS
1178 DelUserInfo (
1179 IN USER_PROFILE_ENTRY *User,
1180 IN EFI_USER_INFO *Info,
1181 IN BOOLEAN Save
1182 )
1183 {
1184 EFI_STATUS Status;
1185 UINTN Offset;
1186 UINTN NextOffset;
1187
1188 //
1189 // Check user information handle.
1190 //
1191 Status = FindUserInfo (User, &Info, FALSE, &Offset);
1192 if (EFI_ERROR (Status)) {
1193 return Status;
1194 }
1195
1196 if (Info->InfoType == EFI_USER_INFO_IDENTIFIER_RECORD) {
1197 return EFI_ACCESS_DENIED;
1198 }
1199
1200 //
1201 // Delete the specified user information.
1202 //
1203 NextOffset = Offset + ALIGN_VARIABLE (Info->InfoSize);
1204 User->UserProfileSize -= ALIGN_VARIABLE (Info->InfoSize);
1205 if (Offset < User->UserProfileSize) {
1206 CopyMem (User->ProfileInfo + Offset, User->ProfileInfo + NextOffset, User->UserProfileSize - Offset);
1207 }
1208
1209 if (Save) {
1210 Status = SaveNvUserProfile (User, FALSE);
1211 }
1212
1213 return Status;
1214 }
1215
1216
1217 /**
1218 Add or update user information.
1219
1220 @param[in] User Point to the user profile.
1221 @param[in, out] UserInfo On entry, points to the user information to modify,
1222 or NULL to add a new UserInfo.
1223 On return, points to the modified user information.
1224 @param[in] Info Points to the new user information.
1225 @param[in] InfoSize The size of Info,in bytes.
1226
1227 @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL.
1228 @retval EFI_ACCESS_DENIED The record is exclusive.
1229 @retval EFI_SUCCESS User information was successfully changed/added.
1230
1231 **/
1232 EFI_STATUS
1233 ModifyUserInfo (
1234 IN USER_PROFILE_ENTRY *User,
1235 IN OUT EFI_USER_INFO **UserInfo,
1236 IN CONST EFI_USER_INFO *Info,
1237 IN UINTN InfoSize
1238 )
1239 {
1240 EFI_STATUS Status;
1241 UINTN PayloadLen;
1242 EFI_USER_INFO *OldInfo;
1243
1244 if ((UserInfo == NULL) || (Info == NULL)) {
1245 return EFI_INVALID_PARAMETER;
1246 }
1247
1248 if (InfoSize < sizeof (EFI_USER_INFO) || InfoSize != Info->InfoSize) {
1249 return EFI_INVALID_PARAMETER;
1250 }
1251
1252 //
1253 // Check user information.
1254 //
1255 if (Info->InfoType == EFI_USER_INFO_IDENTIFIER_RECORD) {
1256 return EFI_ACCESS_DENIED;
1257 }
1258
1259 if (!CheckUserInfo (Info)) {
1260 return EFI_INVALID_PARAMETER;
1261 }
1262
1263
1264 if (*UserInfo == NULL) {
1265 //
1266 // Add new user information.
1267 //
1268 OldInfo = NULL;
1269 do {
1270 Status = FindUserInfoByType (User, &OldInfo, Info->InfoType);
1271 if (EFI_ERROR (Status)) {
1272 break;
1273 }
1274 ASSERT (OldInfo != NULL);
1275
1276 if (((OldInfo->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0) ||
1277 ((Info->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0)) {
1278 //
1279 // Same type can not co-exist for exclusive information.
1280 //
1281 return EFI_ACCESS_DENIED;
1282 }
1283
1284 //
1285 // Check whether it exists in DB.
1286 //
1287 if (Info->InfoSize != OldInfo->InfoSize) {
1288 continue;
1289 }
1290
1291 if (!CompareGuid (&OldInfo->Credential, &Info->Credential)) {
1292 continue;
1293 }
1294
1295 PayloadLen = Info->InfoSize - sizeof (EFI_USER_INFO);
1296 if (PayloadLen == 0) {
1297 continue;
1298 }
1299
1300 if (CompareMem ((UINT8 *)(OldInfo + 1), (UINT8 *)(Info + 1), PayloadLen) != 0) {
1301 continue;
1302 }
1303
1304 //
1305 // Yes. The new info is as same as the one in profile.
1306 //
1307 return EFI_SUCCESS;
1308 } while (!EFI_ERROR (Status));
1309
1310 Status = AddUserInfo (User, (UINT8 *) Info, InfoSize, UserInfo, TRUE);
1311 return Status;
1312 }
1313
1314 //
1315 // Modify existing user information.
1316 //
1317 OldInfo = *UserInfo;
1318 if (OldInfo->InfoType != Info->InfoType) {
1319 return EFI_INVALID_PARAMETER;
1320 }
1321
1322 if (((Info->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0) &&
1323 (OldInfo->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) == 0) {
1324 //
1325 // Try to add exclusive attrib in new info.
1326 // Check whether there is another information with the same type in profile.
1327 //
1328 OldInfo = NULL;
1329 do {
1330 Status = FindUserInfoByType (User, &OldInfo, Info->InfoType);
1331 if (EFI_ERROR (Status)) {
1332 break;
1333 }
1334 if (OldInfo != *UserInfo) {
1335 //
1336 // There is another information with the same type in profile.
1337 // Therefore, can't modify existing user information to add exclusive attribute.
1338 //
1339 return EFI_ACCESS_DENIED;
1340 }
1341 } while (TRUE);
1342 }
1343
1344 Status = DelUserInfo (User, *UserInfo, FALSE);
1345 if (EFI_ERROR (Status)) {
1346 return Status;
1347 }
1348
1349 return AddUserInfo (User, (UINT8 *) Info, InfoSize, UserInfo, TRUE);
1350 }
1351
1352
1353 /**
1354 Delete the user profile from non-volatile memory and database.
1355
1356 @param[in] User Points to the user profile.
1357
1358 @retval EFI_SUCCESS Delete user from the user profile successfully.
1359 @retval Others Fail to delete user from user profile
1360
1361 **/
1362 EFI_STATUS
1363 DelUserProfile (
1364 IN USER_PROFILE_ENTRY *User
1365 )
1366 {
1367 EFI_STATUS Status;
1368 UINTN Index;
1369
1370 //
1371 // Check whether it is in the user profile database.
1372 //
1373 Status = FindUserProfile (&User, FALSE, &Index);
1374 if (EFI_ERROR (Status)) {
1375 return EFI_INVALID_PARAMETER;
1376 }
1377
1378 //
1379 // Check whether it is the current user.
1380 //
1381 if (User == mCurrentUser) {
1382 return EFI_ACCESS_DENIED;
1383 }
1384
1385 //
1386 // Delete user profile from the non-volatile memory.
1387 //
1388 Status = SaveNvUserProfile (mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum - 1], TRUE);
1389 if (EFI_ERROR (Status)) {
1390 return Status;
1391 }
1392 mUserProfileDb->UserProfileNum--;
1393
1394 //
1395 // Modify user profile database.
1396 //
1397 if (Index != mUserProfileDb->UserProfileNum) {
1398 mUserProfileDb->UserProfile[Index] = mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum];
1399 CopyMem (
1400 ((USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[Index])->UserVarName,
1401 User->UserVarName,
1402 sizeof (User->UserVarName)
1403 );
1404 Status = SaveNvUserProfile (mUserProfileDb->UserProfile[Index], FALSE);
1405 if (EFI_ERROR (Status)) {
1406 return Status;
1407 }
1408 }
1409 //
1410 // Delete user profile information.
1411 //
1412 if (User->ProfileInfo != NULL) {
1413 FreePool (User->ProfileInfo);
1414 }
1415
1416 FreePool (User);
1417 return EFI_SUCCESS;
1418 }
1419
1420
1421 /**
1422 Add user profile to user profile database.
1423
1424 @param[out] UserProfile Point to the newly added user profile.
1425 @param[in] ProfileSize The size of the user profile.
1426 @param[in] ProfileInfo Point to the user profie data.
1427 @param[in] Save If TRUE, save the new added profile to NV flash.
1428 If FALSE, don't save the profile to NV flash.
1429
1430 @retval EFI_SUCCESS Add user profile to user profile database successfully.
1431 @retval Others Fail to add user profile to user profile database.
1432
1433 **/
1434 EFI_STATUS
1435 AddUserProfile (
1436 OUT USER_PROFILE_ENTRY **UserProfile, OPTIONAL
1437 IN UINTN ProfileSize,
1438 IN UINT8 *ProfileInfo,
1439 IN BOOLEAN Save
1440 )
1441 {
1442 EFI_STATUS Status;
1443 USER_PROFILE_ENTRY *User;
1444
1445 //
1446 // Check the data format to be added.
1447 //
1448 if (!CheckProfileInfo (ProfileInfo, ProfileSize)) {
1449 return EFI_SECURITY_VIOLATION;
1450 }
1451
1452 //
1453 // Create user profile entry.
1454 //
1455 User = AllocateZeroPool (sizeof (USER_PROFILE_ENTRY));
1456 if (User == NULL) {
1457 return EFI_OUT_OF_RESOURCES;
1458 }
1459 //
1460 // Add the entry to the user profile database.
1461 //
1462 if (mUserProfileDb->UserProfileNum == mUserProfileDb->MaxProfileNum) {
1463 if (!ExpandUsermUserProfileDb ()) {
1464 FreePool (User);
1465 return EFI_OUT_OF_RESOURCES;
1466 }
1467 }
1468
1469 UnicodeSPrint (
1470 User->UserVarName,
1471 sizeof (User->UserVarName),
1472 L"User%04x",
1473 mUserProfileDb->UserProfileNum
1474 );
1475 User->UserProfileSize = 0;
1476 User->MaxProfileSize = 0;
1477 User->ProfileInfo = NULL;
1478 mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum] = (EFI_USER_PROFILE_HANDLE) User;
1479 mUserProfileDb->UserProfileNum++;
1480
1481 //
1482 // Add user profile information.
1483 //
1484 Status = AddUserInfo (User, ProfileInfo, ProfileSize, NULL, Save);
1485 if (EFI_ERROR (Status)) {
1486 DelUserProfile (User);
1487 return Status;
1488 }
1489 //
1490 // Set new user profile handle.
1491 //
1492 if (UserProfile != NULL) {
1493 *UserProfile = User;
1494 }
1495
1496 return EFI_SUCCESS;
1497 }
1498
1499
1500 /**
1501 This function creates a new user profile with only a new user identifier
1502 attached and returns its handle. The user profile is non-volatile, but the
1503 handle User can change across reboots.
1504
1505 @param[out] User Handle of a new user profile.
1506
1507 @retval EFI_SUCCESS User profile was successfully created.
1508 @retval Others Fail to create user profile
1509
1510 **/
1511 EFI_STATUS
1512 CreateUserProfile (
1513 OUT USER_PROFILE_ENTRY **User
1514 )
1515 {
1516 EFI_STATUS Status;
1517 EFI_USER_INFO *UserInfo;
1518
1519 if (User == NULL) {
1520 return EFI_INVALID_PARAMETER;
1521 }
1522 //
1523 // Generate user id information.
1524 //
1525 UserInfo = AllocateZeroPool (sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER));
1526 if (UserInfo == NULL) {
1527 return EFI_OUT_OF_RESOURCES;
1528 }
1529
1530 UserInfo->InfoType = EFI_USER_INFO_IDENTIFIER_RECORD;
1531 UserInfo->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER);
1532 UserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;
1533 GenerateUserId ((UINT8 *) (UserInfo + 1));
1534
1535 //
1536 // Add user profile to the user profile database.
1537 //
1538 Status = AddUserProfile (User, UserInfo->InfoSize, (UINT8 *) UserInfo, TRUE);
1539 FreePool (UserInfo);
1540 return Status;
1541 }
1542
1543
1544 /**
1545 Add a default user profile to user profile database.
1546
1547 @retval EFI_SUCCESS A default user profile is added successfully.
1548 @retval Others Fail to add a default user profile
1549
1550 **/
1551 EFI_STATUS
1552 AddDefaultUserProfile (
1553 VOID
1554 )
1555 {
1556 EFI_STATUS Status;
1557 USER_PROFILE_ENTRY *User;
1558 EFI_USER_INFO *Info;
1559 EFI_USER_INFO *NewInfo;
1560 EFI_USER_INFO_CREATE_DATE CreateDate;
1561 EFI_USER_INFO_USAGE_COUNT UsageCount;
1562 EFI_USER_INFO_ACCESS_CONTROL *Access;
1563 EFI_USER_INFO_IDENTITY_POLICY *Policy;
1564
1565 //
1566 // Create a user profile.
1567 //
1568 Status = CreateUserProfile (&User);
1569 if (EFI_ERROR (Status)) {
1570 return Status;
1571 }
1572
1573 //
1574 // Allocate a buffer to add all default user information.
1575 //
1576 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + INFO_PAYLOAD_SIZE);
1577 if (Info == NULL) {
1578 return EFI_OUT_OF_RESOURCES;
1579 }
1580
1581 //
1582 // Add user name.
1583 //
1584 Info->InfoType = EFI_USER_INFO_NAME_RECORD;
1585 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;
1586 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (mUserName);
1587 CopyMem ((UINT8 *) (Info + 1), mUserName, sizeof (mUserName));
1588 NewInfo = NULL;
1589 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);
1590 if (EFI_ERROR (Status)) {
1591 goto Done;
1592 }
1593
1594 //
1595 // Add user profile create date record.
1596 //
1597 Info->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD;
1598 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;
1599 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE);
1600 Status = gRT->GetTime (&CreateDate, NULL);
1601 if (EFI_ERROR (Status)) {
1602 goto Done;
1603 }
1604
1605 CopyMem ((UINT8 *) (Info + 1), &CreateDate, sizeof (EFI_USER_INFO_CREATE_DATE));
1606 NewInfo = NULL;
1607 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);
1608 if (EFI_ERROR (Status)) {
1609 goto Done;
1610 }
1611
1612 //
1613 // Add user profile usage count record.
1614 //
1615 Info->InfoType = EFI_USER_INFO_USAGE_COUNT_RECORD;
1616 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;
1617 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_COUNT);
1618 UsageCount = 0;
1619 CopyMem ((UINT8 *) (Info + 1), &UsageCount, sizeof (EFI_USER_INFO_USAGE_COUNT));
1620 NewInfo = NULL;
1621 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);
1622 if (EFI_ERROR (Status)) {
1623 goto Done;
1624 }
1625
1626 //
1627 // Add user access right.
1628 //
1629 Info->InfoType = EFI_USER_INFO_ACCESS_POLICY_RECORD;
1630 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;
1631 Access = (EFI_USER_INFO_ACCESS_CONTROL *) (Info + 1);
1632 Access->Type = EFI_USER_INFO_ACCESS_MANAGE;
1633 Access->Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL);
1634 Info->InfoSize = sizeof (EFI_USER_INFO) + Access->Size;
1635 NewInfo = NULL;
1636 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);
1637 if (EFI_ERROR (Status)) {
1638 goto Done;
1639 }
1640
1641 //
1642 // Add user identity policy.
1643 //
1644 Info->InfoType = EFI_USER_INFO_IDENTITY_POLICY_RECORD;
1645 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PRIVATE | EFI_USER_INFO_EXCLUSIVE;
1646 Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (Info + 1);
1647 Policy->Type = EFI_USER_INFO_IDENTITY_TRUE;
1648 Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY);
1649 Info->InfoSize = sizeof (EFI_USER_INFO) + Policy->Length;
1650 NewInfo = NULL;
1651 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);
1652
1653 Done:
1654 FreePool (Info);
1655 return Status;
1656 }
1657
1658
1659 /**
1660 Publish current user information into EFI System Configuration Table.
1661
1662 By UEFI spec, the User Identity Manager will publish the current user profile
1663 into the EFI System Configuration Table. Currently, only the user identifier and user
1664 name are published.
1665
1666 @retval EFI_SUCCESS Current user information is published successfully.
1667 @retval Others Fail to publish current user information
1668
1669 **/
1670 EFI_STATUS
1671 PublishUserTable (
1672 VOID
1673 )
1674 {
1675 EFI_STATUS Status;
1676 EFI_CONFIGURATION_TABLE *EfiConfigurationTable;
1677 EFI_USER_INFO_TABLE *UserInfoTable;
1678 EFI_USER_INFO *IdInfo;
1679 EFI_USER_INFO *NameInfo;
1680
1681 Status = EfiGetSystemConfigurationTable (
1682 &gEfiUserManagerProtocolGuid,
1683 (VOID **) &EfiConfigurationTable
1684 );
1685 if (!EFI_ERROR (Status)) {
1686 //
1687 // The table existed!
1688 //
1689 return EFI_SUCCESS;
1690 }
1691
1692 //
1693 // Get user ID information.
1694 //
1695 IdInfo = NULL;
1696 Status = FindUserInfoByType (mCurrentUser, &IdInfo, EFI_USER_INFO_IDENTIFIER_RECORD);
1697 if (EFI_ERROR (Status)) {
1698 return Status;
1699
1700 }
1701 //
1702 // Get user name information.
1703 //
1704 NameInfo = NULL;
1705 Status = FindUserInfoByType (mCurrentUser, &NameInfo, EFI_USER_INFO_NAME_RECORD);
1706 if (EFI_ERROR (Status)) {
1707 return Status;
1708 }
1709
1710 //
1711 // Allocate a buffer for user information table.
1712 //
1713 UserInfoTable = (EFI_USER_INFO_TABLE *) AllocateRuntimePool (
1714 sizeof (EFI_USER_INFO_TABLE) +
1715 IdInfo->InfoSize +
1716 NameInfo->InfoSize
1717 );
1718 if (UserInfoTable == NULL) {
1719 Status = EFI_OUT_OF_RESOURCES;
1720 return Status;
1721 }
1722
1723 UserInfoTable->Size = sizeof (EFI_USER_INFO_TABLE);
1724
1725 //
1726 // Append the user information to the user info table
1727 //
1728 CopyMem ((UINT8 *) UserInfoTable + UserInfoTable->Size, (UINT8 *) IdInfo, IdInfo->InfoSize);
1729 UserInfoTable->Size += IdInfo->InfoSize;
1730
1731 CopyMem ((UINT8 *) UserInfoTable + UserInfoTable->Size, (UINT8 *) NameInfo, NameInfo->InfoSize);
1732 UserInfoTable->Size += NameInfo->InfoSize;
1733
1734 Status = gBS->InstallConfigurationTable (&gEfiUserManagerProtocolGuid, (VOID *) UserInfoTable);
1735 return Status;
1736 }
1737
1738
1739 /**
1740 Get the user's identity type.
1741
1742 The identify manager only supports the identity policy in which the credential
1743 provider handles are connected by the operator 'AND' or 'OR'.
1744
1745
1746 @param[in] User Handle of a user profile.
1747 @param[out] PolicyType Point to the identity type.
1748
1749 @retval EFI_SUCCESS Get user's identity type successfully.
1750 @retval Others Fail to get user's identity type.
1751
1752 **/
1753 EFI_STATUS
1754 GetIdentifyType (
1755 IN EFI_USER_PROFILE_HANDLE User,
1756 OUT UINT8 *PolicyType
1757 )
1758 {
1759 EFI_STATUS Status;
1760 EFI_USER_INFO *IdentifyInfo;
1761 UINTN TotalLen;
1762 EFI_USER_INFO_IDENTITY_POLICY *Identity;
1763
1764 //
1765 // Get user identify policy information.
1766 //
1767 IdentifyInfo = NULL;
1768 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);
1769 if (EFI_ERROR (Status)) {
1770 return Status;
1771 }
1772 ASSERT (IdentifyInfo != NULL);
1773
1774 //
1775 // Search the user identify policy according to type.
1776 //
1777 TotalLen = 0;
1778 *PolicyType = EFI_USER_INFO_IDENTITY_FALSE;
1779 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {
1780 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);
1781 if (Identity->Type == EFI_USER_INFO_IDENTITY_AND) {
1782 *PolicyType = EFI_USER_INFO_IDENTITY_AND;
1783 break;
1784 }
1785
1786 if (Identity->Type == EFI_USER_INFO_IDENTITY_OR) {
1787 *PolicyType = EFI_USER_INFO_IDENTITY_OR;
1788 break;
1789 }
1790 TotalLen += Identity->Length;
1791 }
1792 return EFI_SUCCESS;
1793 }
1794
1795
1796 /**
1797 Identify the User by the specfied provider.
1798
1799 @param[in] User Handle of a user profile.
1800 @param[in] Provider Points to the identifier of credential provider.
1801
1802 @retval EFI_INVALID_PARAMETER Provider is NULL.
1803 @retval EFI_NOT_FOUND Fail to identify the specified user.
1804 @retval EFI_SUCCESS User is identified successfully.
1805
1806 **/
1807 EFI_STATUS
1808 IdentifyByProviderId (
1809 IN EFI_USER_PROFILE_HANDLE User,
1810 IN EFI_GUID *Provider
1811 )
1812 {
1813 EFI_STATUS Status;
1814 EFI_USER_INFO_IDENTIFIER UserId;
1815 UINTN Index;
1816 EFI_CREDENTIAL_LOGON_FLAGS AutoLogon;
1817 EFI_HII_HANDLE HiiHandle;
1818 EFI_GUID FormSetId;
1819 EFI_FORM_ID FormId;
1820 EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;
1821
1822 if (Provider == NULL) {
1823 return EFI_INVALID_PARAMETER;
1824 }
1825
1826 //
1827 // Check the user ID identified by the specified credential provider.
1828 //
1829 for (Index = 0; Index < mProviderDb->Count; Index++) {
1830 //
1831 // Check credential provider class.
1832 //
1833 UserCredential = mProviderDb->Provider[Index];
1834 if (CompareGuid (&UserCredential->Identifier, Provider)) {
1835 Status = UserCredential->Select (UserCredential, &AutoLogon);
1836 if (EFI_ERROR (Status)) {
1837 return Status;
1838 }
1839
1840 if ((AutoLogon & EFI_CREDENTIAL_LOGON_FLAG_AUTO) == 0) {
1841 //
1842 // Get credential provider form.
1843 //
1844 Status = UserCredential->Form (
1845 UserCredential,
1846 &HiiHandle,
1847 &FormSetId,
1848 &FormId
1849 );
1850 if (!EFI_ERROR (Status)) {
1851 //
1852 // Send form to get user input.
1853 //
1854 Status = mCallbackInfo->FormBrowser2->SendForm (
1855 mCallbackInfo->FormBrowser2,
1856 &HiiHandle,
1857 1,
1858 &FormSetId,
1859 FormId,
1860 NULL,
1861 NULL
1862 );
1863 if (EFI_ERROR (Status)) {
1864 return Status;
1865 }
1866 }
1867 }
1868
1869 Status = UserCredential->User (UserCredential, User, &UserId);
1870 if (EFI_ERROR (Status)) {
1871 return Status;
1872 }
1873
1874 Status = UserCredential->Deselect (UserCredential);
1875 if (EFI_ERROR (Status)) {
1876 return Status;
1877 }
1878
1879 return EFI_SUCCESS;
1880 }
1881 }
1882
1883 return EFI_NOT_FOUND;
1884 }
1885
1886
1887 /**
1888 Update user information when user is logon on successfully.
1889
1890 @param[in] User Points to user profile.
1891
1892 @retval EFI_SUCCESS Update user information successfully.
1893 @retval Others Fail to update user information.
1894
1895 **/
1896 EFI_STATUS
1897 UpdateUserInfo (
1898 IN USER_PROFILE_ENTRY *User
1899 )
1900 {
1901 EFI_STATUS Status;
1902 EFI_USER_INFO *Info;
1903 EFI_USER_INFO *NewInfo;
1904 EFI_USER_INFO_CREATE_DATE Date;
1905 EFI_USER_INFO_USAGE_COUNT UsageCount;
1906 UINTN InfoLen;
1907
1908 //
1909 // Allocate a buffer to update user's date record and usage record.
1910 //
1911 InfoLen = MAX (sizeof (EFI_USER_INFO_CREATE_DATE), sizeof (EFI_USER_INFO_USAGE_COUNT));
1912 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + InfoLen);
1913 if (Info == NULL) {
1914 return EFI_OUT_OF_RESOURCES;
1915 }
1916
1917 //
1918 // Check create date record.
1919 //
1920 NewInfo = NULL;
1921 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_CREATE_DATE_RECORD);
1922 if (Status == EFI_NOT_FOUND) {
1923 Info->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD;
1924 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;
1925 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE);
1926 Status = gRT->GetTime (&Date, NULL);
1927 if (EFI_ERROR (Status)) {
1928 FreePool (Info);
1929 return Status;
1930 }
1931
1932 CopyMem ((UINT8 *) (Info + 1), &Date, sizeof (EFI_USER_INFO_CREATE_DATE));
1933 NewInfo = NULL;
1934 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);
1935 if (EFI_ERROR (Status)) {
1936 FreePool (Info);
1937 return Status;
1938 }
1939 }
1940
1941 //
1942 // Update usage date record.
1943 //
1944 NewInfo = NULL;
1945 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_USAGE_DATE_RECORD);
1946 if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {
1947 Info->InfoType = EFI_USER_INFO_USAGE_DATE_RECORD;
1948 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;
1949 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_DATE);
1950 Status = gRT->GetTime (&Date, NULL);
1951 if (EFI_ERROR (Status)) {
1952 FreePool (Info);
1953 return Status;
1954 }
1955
1956 CopyMem ((UINT8 *) (Info + 1), &Date, sizeof (EFI_USER_INFO_USAGE_DATE));
1957 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);
1958 if (EFI_ERROR (Status)) {
1959 FreePool (Info);
1960 return Status;
1961 }
1962 }
1963
1964 //
1965 // Update usage count record.
1966 //
1967 UsageCount = 0;
1968 NewInfo = NULL;
1969 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_USAGE_COUNT_RECORD);
1970 //
1971 // Get usage count.
1972 //
1973 if (Status == EFI_SUCCESS) {
1974 CopyMem (&UsageCount, (UINT8 *) (NewInfo + 1), sizeof (EFI_USER_INFO_USAGE_COUNT));
1975 }
1976
1977 UsageCount++;
1978 if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {
1979 Info->InfoType = EFI_USER_INFO_USAGE_COUNT_RECORD;
1980 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;
1981 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_COUNT);
1982 CopyMem ((UINT8 *) (Info + 1), &UsageCount, sizeof (EFI_USER_INFO_USAGE_COUNT));
1983 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);
1984 if (EFI_ERROR (Status)) {
1985 FreePool (Info);
1986 return Status;
1987 }
1988 }
1989
1990 FreePool (Info);
1991 return EFI_SUCCESS;
1992 }
1993
1994
1995 /**
1996 Add a credenetial provider item in form.
1997
1998 @param[in] ProviderGuid Points to the identifir of credential provider.
1999 @param[in] OpCodeHandle Points to container for dynamic created opcodes.
2000
2001 **/
2002 VOID
2003 AddProviderSelection (
2004 IN EFI_GUID *ProviderGuid,
2005 IN VOID *OpCodeHandle
2006 )
2007 {
2008 EFI_HII_HANDLE HiiHandle;
2009 EFI_STRING_ID ProvID;
2010 CHAR16 *ProvStr;
2011 UINTN Index;
2012 EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;
2013
2014 for (Index = 0; Index < mProviderDb->Count; Index++) {
2015 UserCredential = mProviderDb->Provider[Index];
2016 if (CompareGuid (&UserCredential->Identifier, ProviderGuid)) {
2017 //
2018 // Add credential provider selection.
2019 //
2020 UserCredential->Title (UserCredential, &HiiHandle, &ProvID);
2021 ProvStr = HiiGetString (HiiHandle, ProvID, NULL);
2022 if (ProvStr == NULL) {
2023 continue ;
2024 }
2025 ProvID = HiiSetString (mCallbackInfo->HiiHandle, 0, ProvStr, NULL);
2026 FreePool (ProvStr);
2027 HiiCreateActionOpCode (
2028 OpCodeHandle, // Container for dynamic created opcodes
2029 (EFI_QUESTION_ID)(LABEL_PROVIDER_NAME + Index), // Question ID
2030 ProvID, // Prompt text
2031 STRING_TOKEN (STR_NULL_STRING), // Help text
2032 EFI_IFR_FLAG_CALLBACK, // Question flag
2033 0 // Action String ID
2034 );
2035 break;
2036 }
2037 }
2038 }
2039
2040
2041 /**
2042 Add a username item in form.
2043
2044 @param[in] Index The index of the user in the user name list.
2045 @param[in] User Points to the user profile whose username is added.
2046 @param[in] OpCodeHandle Points to container for dynamic created opcodes.
2047
2048 @retval EFI_SUCCESS Add a username successfully.
2049 @retval Others Fail to add a username.
2050
2051 **/
2052 EFI_STATUS
2053 AddUserSelection (
2054 IN UINT16 Index,
2055 IN USER_PROFILE_ENTRY *User,
2056 IN VOID *OpCodeHandle
2057 )
2058 {
2059 EFI_STRING_ID UserName;
2060 EFI_STATUS Status;
2061 EFI_USER_INFO *UserInfo;
2062
2063 UserInfo = NULL;
2064 Status = FindUserInfoByType (User, &UserInfo, EFI_USER_INFO_NAME_RECORD);
2065 if (EFI_ERROR (Status)) {
2066 return Status;
2067 }
2068
2069 //
2070 // Add user name selection.
2071 //
2072 UserName = HiiSetString (mCallbackInfo->HiiHandle, 0, (EFI_STRING) (UserInfo + 1), NULL);
2073 if (UserName == 0) {
2074 return EFI_OUT_OF_RESOURCES;
2075 }
2076
2077 HiiCreateGotoOpCode (
2078 OpCodeHandle, // Container for dynamic created opcodes
2079 FORMID_PROVIDER_FORM, // Target Form ID
2080 UserName, // Prompt text
2081 STRING_TOKEN (STR_NULL_STRING), // Help text
2082 EFI_IFR_FLAG_CALLBACK, // Question flag
2083 (UINT16) Index // Question ID
2084 );
2085
2086 return EFI_SUCCESS;
2087 }
2088
2089
2090 /**
2091 Identify the user whose identity policy does not contain the operator 'OR'.
2092
2093 @param[in] User Points to the user profile.
2094
2095 @retval EFI_SUCCESS The specified user is identified successfully.
2096 @retval Others Fail to identify the user.
2097
2098 **/
2099 EFI_STATUS
2100 IdentifyAndTypeUser (
2101 IN USER_PROFILE_ENTRY *User
2102 )
2103 {
2104 EFI_STATUS Status;
2105 EFI_USER_INFO *IdentifyInfo;
2106 BOOLEAN Success;
2107 UINTN TotalLen;
2108 UINTN ValueLen;
2109 EFI_USER_INFO_IDENTITY_POLICY *Identity;
2110
2111 //
2112 // Get user identify policy information.
2113 //
2114 IdentifyInfo = NULL;
2115 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);
2116 if (EFI_ERROR (Status)) {
2117 return Status;
2118 }
2119 ASSERT (IdentifyInfo != NULL);
2120
2121 //
2122 // Check each part of identification policy expression.
2123 //
2124 Success = FALSE;
2125 TotalLen = 0;
2126 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {
2127 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);
2128 ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);
2129 switch (Identity->Type) {
2130
2131 case EFI_USER_INFO_IDENTITY_FALSE:
2132 //
2133 // Check False option.
2134 //
2135 Success = FALSE;
2136 break;
2137
2138 case EFI_USER_INFO_IDENTITY_TRUE:
2139 //
2140 // Check True option.
2141 //
2142 Success = TRUE;
2143 break;
2144
2145 case EFI_USER_INFO_IDENTITY_NOT:
2146 //
2147 // Check negative operation.
2148 //
2149 break;
2150
2151 case EFI_USER_INFO_IDENTITY_AND:
2152 //
2153 // Check and operation.
2154 //
2155 if (!Success) {
2156 return EFI_NOT_READY;
2157 }
2158
2159 Success = FALSE;
2160 break;
2161
2162 case EFI_USER_INFO_IDENTITY_OR:
2163 //
2164 // Check or operation.
2165 //
2166 if (Success) {
2167 return EFI_SUCCESS;
2168 }
2169 break;
2170
2171 case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:
2172 //
2173 // Check credential provider by type.
2174 //
2175 break;
2176
2177 case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:
2178 //
2179 // Check credential provider by ID.
2180 //
2181 if (ValueLen != sizeof (EFI_GUID)) {
2182 return EFI_INVALID_PARAMETER;
2183 }
2184
2185 Status = IdentifyByProviderId (User, (EFI_GUID *) (Identity + 1));
2186 if (EFI_ERROR (Status)) {
2187 return Status;
2188 }
2189
2190 Success = TRUE;
2191 break;
2192
2193 default:
2194 return EFI_INVALID_PARAMETER;
2195 break;
2196 }
2197
2198 TotalLen += Identity->Length;
2199 }
2200
2201 if (TotalLen != IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {
2202 return EFI_INVALID_PARAMETER;
2203 }
2204
2205 if (!Success) {
2206 return EFI_NOT_READY;
2207 }
2208
2209 return EFI_SUCCESS;
2210 }
2211
2212
2213 /**
2214 Identify the user whose identity policy does not contain the operator 'AND'.
2215
2216 @param[in] User Points to the user profile.
2217
2218 @retval EFI_SUCCESS The specified user is identified successfully.
2219 @retval Others Fail to identify the user.
2220
2221 **/
2222 EFI_STATUS
2223 IdentifyOrTypeUser (
2224 IN USER_PROFILE_ENTRY *User
2225 )
2226 {
2227 EFI_STATUS Status;
2228 EFI_USER_INFO *IdentifyInfo;
2229 UINTN TotalLen;
2230 UINTN ValueLen;
2231 EFI_USER_INFO_IDENTITY_POLICY *Identity;
2232 VOID *StartOpCodeHandle;
2233 VOID *EndOpCodeHandle;
2234 EFI_IFR_GUID_LABEL *StartLabel;
2235 EFI_IFR_GUID_LABEL *EndLabel;
2236
2237 //
2238 // Get user identify policy information.
2239 //
2240 IdentifyInfo = NULL;
2241 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);
2242 if (EFI_ERROR (Status)) {
2243 return Status;
2244 }
2245 ASSERT (IdentifyInfo != NULL);
2246
2247 //
2248 // Initialize the container for dynamic opcodes.
2249 //
2250 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
2251 ASSERT (StartOpCodeHandle != NULL);
2252
2253 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
2254 ASSERT (EndOpCodeHandle != NULL);
2255
2256 //
2257 // Create Hii Extend Label OpCode.
2258 //
2259 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
2260 StartOpCodeHandle,
2261 &gEfiIfrTianoGuid,
2262 NULL,
2263 sizeof (EFI_IFR_GUID_LABEL)
2264 );
2265 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
2266 StartLabel->Number = LABEL_PROVIDER_NAME;
2267
2268 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
2269 EndOpCodeHandle,
2270 &gEfiIfrTianoGuid,
2271 NULL,
2272 sizeof (EFI_IFR_GUID_LABEL)
2273 );
2274 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
2275 EndLabel->Number = LABEL_END;
2276
2277 //
2278 // Add the providers that exists in the user's policy.
2279 //
2280 TotalLen = 0;
2281 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {
2282 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);
2283 ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);
2284 if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {
2285 AddProviderSelection ((EFI_GUID *) (Identity + 1), StartOpCodeHandle);
2286 }
2287
2288 TotalLen += Identity->Length;
2289 }
2290
2291 HiiUpdateForm (
2292 mCallbackInfo->HiiHandle, // HII handle
2293 &gUserIdentifyManagerGuid,// Formset GUID
2294 FORMID_PROVIDER_FORM, // Form ID
2295 StartOpCodeHandle, // Label for where to insert opcodes
2296 EndOpCodeHandle // Replace data
2297 );
2298
2299 HiiFreeOpCodeHandle (StartOpCodeHandle);
2300 HiiFreeOpCodeHandle (EndOpCodeHandle);
2301
2302 return EFI_SUCCESS;
2303 }
2304
2305
2306 /**
2307 This function processes the results of changes in configuration.
2308
2309 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
2310 @param Action Specifies the type of action taken by the browser.
2311 @param QuestionId A unique value which is sent to the original
2312 exporting driver so that it can identify the type
2313 of data to expect.
2314 @param Type The type of value for the question.
2315 @param Value A pointer to the data being sent to the original
2316 exporting driver.
2317 @param ActionRequest On return, points to the action requested by the
2318 callback function.
2319
2320 @retval EFI_SUCCESS The callback successfully handled the action.
2321 @retval Others Fail to handle the action.
2322
2323 **/
2324 EFI_STATUS
2325 EFIAPI
2326 UserIdentifyManagerCallback (
2327 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
2328 IN EFI_BROWSER_ACTION Action,
2329 IN EFI_QUESTION_ID QuestionId,
2330 IN UINT8 Type,
2331 IN EFI_IFR_TYPE_VALUE *Value,
2332 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
2333 )
2334 {
2335 EFI_STATUS Status;
2336 USER_PROFILE_ENTRY *User;
2337 UINT8 PolicyType;
2338 UINT16 Index;
2339 VOID *StartOpCodeHandle;
2340 VOID *EndOpCodeHandle;
2341 EFI_IFR_GUID_LABEL *StartLabel;
2342 EFI_IFR_GUID_LABEL *EndLabel;
2343
2344 Status = EFI_SUCCESS;
2345
2346 switch (Action) {
2347 case EFI_BROWSER_ACTION_FORM_OPEN:
2348 {
2349 //
2350 // Update user Form when user Form is opened.
2351 // This will be done only in FORM_OPEN CallBack of question with FORM_OPEN_QUESTION_ID from user Form.
2352 //
2353 if (QuestionId != FORM_OPEN_QUESTION_ID) {
2354 return EFI_SUCCESS;
2355 }
2356
2357 //
2358 // Initialize the container for dynamic opcodes.
2359 //
2360 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
2361 ASSERT (StartOpCodeHandle != NULL);
2362
2363 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
2364 ASSERT (EndOpCodeHandle != NULL);
2365
2366 //
2367 // Create Hii Extend Label OpCode.
2368 //
2369 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
2370 StartOpCodeHandle,
2371 &gEfiIfrTianoGuid,
2372 NULL,
2373 sizeof (EFI_IFR_GUID_LABEL)
2374 );
2375 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
2376 StartLabel->Number = LABEL_USER_NAME;
2377
2378 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
2379 EndOpCodeHandle,
2380 &gEfiIfrTianoGuid,
2381 NULL,
2382 sizeof (EFI_IFR_GUID_LABEL)
2383 );
2384 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
2385 EndLabel->Number = LABEL_END;
2386
2387 //
2388 // Add all the user profile in the user profile database.
2389 //
2390 for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {
2391 User = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[Index];
2392 AddUserSelection ((UINT16)(LABEL_USER_NAME + Index), User, StartOpCodeHandle);
2393 }
2394
2395 HiiUpdateForm (
2396 mCallbackInfo->HiiHandle, // HII handle
2397 &gUserIdentifyManagerGuid,// Formset GUID
2398 FORMID_USER_FORM, // Form ID
2399 StartOpCodeHandle, // Label for where to insert opcodes
2400 EndOpCodeHandle // Replace data
2401 );
2402
2403 HiiFreeOpCodeHandle (StartOpCodeHandle);
2404 HiiFreeOpCodeHandle (EndOpCodeHandle);
2405
2406 return EFI_SUCCESS;
2407 }
2408 break;
2409
2410 case EFI_BROWSER_ACTION_FORM_CLOSE:
2411 Status = EFI_SUCCESS;
2412 break;
2413
2414 case EFI_BROWSER_ACTION_CHANGING:
2415 {
2416 if (QuestionId >= LABEL_PROVIDER_NAME) {
2417 //
2418 // QuestionId comes from the second Form (Select a Credential Provider if identity
2419 // policy is OR type). Identify the user by the selected provider.
2420 //
2421 Status = IdentifyByProviderId (mCurrentUser, &mProviderDb->Provider[QuestionId & 0xFFF]->Identifier);
2422 if (Status == EFI_SUCCESS) {
2423 mIdentified = TRUE;
2424 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
2425 }
2426 return EFI_SUCCESS;
2427 }
2428
2429 //
2430 // QuestionId comes from the first Form (Select a user to identify).
2431 //
2432 User = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[QuestionId & 0xFFF];
2433 Status = GetIdentifyType (User, &PolicyType);
2434 if (EFI_ERROR (Status)) {
2435 return Status;
2436 }
2437
2438 if (PolicyType == EFI_USER_INFO_IDENTITY_OR) {
2439 //
2440 // Identify the user by "OR" logical.
2441 //
2442 Status = IdentifyOrTypeUser (User);
2443 if (EFI_ERROR (Status)) {
2444 return Status;
2445 }
2446
2447 mCurrentUser = (EFI_USER_PROFILE_HANDLE) User;
2448 } else {
2449 //
2450 // Identify the user by "AND" logical.
2451 //
2452 Status = IdentifyAndTypeUser (User);
2453 if (EFI_ERROR (Status)) {
2454 return Status;
2455 }
2456
2457 mCurrentUser = (EFI_USER_PROFILE_HANDLE) User;
2458 mIdentified = TRUE;
2459 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
2460 }
2461 }
2462 break;
2463
2464 default:
2465 //
2466 // All other action return unsupported.
2467 //
2468 Status = EFI_UNSUPPORTED;
2469 break;
2470 }
2471
2472
2473 return Status;
2474 }
2475
2476
2477 /**
2478 This function construct user profile database from user data saved in the Flash.
2479 If no user is found in Flash, add one default user "administrator" in the user
2480 profile database.
2481
2482 @retval EFI_SUCCESS Init user profile database successfully.
2483 @retval Others Fail to init user profile database.
2484
2485 **/
2486 EFI_STATUS
2487 InitUserProfileDb (
2488 VOID
2489 )
2490 {
2491 EFI_STATUS Status;
2492 UINT8 *VarData;
2493 UINTN VarSize;
2494 UINTN CurVarSize;
2495 CHAR16 VarName[10];
2496 UINTN Index;
2497 UINT32 VarAttr;
2498
2499 if (mUserProfileDb != NULL) {
2500 //
2501 // The user profiles had been already initialized.
2502 //
2503 return EFI_SUCCESS;
2504 }
2505
2506 //
2507 // Init user profile database structure.
2508 //
2509 if (!ExpandUsermUserProfileDb ()) {
2510 return EFI_OUT_OF_RESOURCES;
2511 }
2512
2513 CurVarSize = DEFAULT_PROFILE_SIZE;
2514 VarData = AllocateZeroPool (CurVarSize);
2515 if (VarData == NULL) {
2516 return EFI_OUT_OF_RESOURCES;
2517 }
2518
2519 //
2520 // Get all user proifle entries.
2521 //
2522 Index = 0;
2523 while (TRUE) {
2524 //
2525 // Get variable name.
2526 //
2527 UnicodeSPrint (
2528 VarName,
2529 sizeof (VarName),
2530 L"User%04x",
2531 Index
2532 );
2533 Index++;
2534
2535 //
2536 // Get variable value.
2537 //
2538 VarSize = CurVarSize;
2539 Status = gRT->GetVariable (VarName, &gUserIdentifyManagerGuid, &VarAttr, &VarSize, VarData);
2540 if (Status == EFI_BUFFER_TOO_SMALL) {
2541 FreePool (VarData);
2542 VarData = AllocatePool (VarSize);
2543 if (VarData == NULL) {
2544 Status = EFI_OUT_OF_RESOURCES;
2545 break;
2546 }
2547
2548 CurVarSize = VarSize;
2549 Status = gRT->GetVariable (VarName, &gUserIdentifyManagerGuid, &VarAttr, &VarSize, VarData);
2550 }
2551
2552 if (EFI_ERROR (Status)) {
2553 if (Status == EFI_NOT_FOUND) {
2554 Status = EFI_SUCCESS;
2555 }
2556 break;
2557 }
2558
2559 //
2560 // Check variable attributes.
2561 //
2562 if (VarAttr != (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)) {
2563 Status = gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);
2564 continue;
2565 }
2566
2567 //
2568 // Add user profile to the user profile database.
2569 //
2570 Status = AddUserProfile (NULL, VarSize, VarData, FALSE);
2571 if (EFI_ERROR (Status)) {
2572 if (Status == EFI_SECURITY_VIOLATION) {
2573 //
2574 // Delete invalid user profile
2575 //
2576 gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);
2577 } else if (Status == EFI_OUT_OF_RESOURCES) {
2578 break;
2579 }
2580 } else {
2581 //
2582 // Delete and save the profile again if some invalid profiles are deleted.
2583 //
2584 if (mUserProfileDb->UserProfileNum < Index) {
2585 gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);
2586 SaveNvUserProfile (mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum - 1], FALSE);
2587 }
2588 }
2589 }
2590
2591 if (VarData != NULL) {
2592 FreePool (VarData);
2593 }
2594
2595 if (EFI_ERROR (Status)) {
2596 return Status;
2597 }
2598
2599 //
2600 // Check whether the user profile database is empty.
2601 //
2602 if (mUserProfileDb->UserProfileNum == 0) {
2603 Status = AddDefaultUserProfile ();
2604 }
2605
2606 return Status;
2607 }
2608
2609
2610 /**
2611 This function collects all the credential providers and saves to mProviderDb.
2612
2613 @retval EFI_SUCCESS Collect credential providers successfully.
2614 @retval Others Fail to collect credential providers.
2615
2616 **/
2617 EFI_STATUS
2618 InitProviderInfo (
2619 VOID
2620 )
2621 {
2622 EFI_STATUS Status;
2623 UINTN HandleCount;
2624 EFI_HANDLE *HandleBuf;
2625 UINTN Index;
2626
2627 if (mProviderDb != NULL) {
2628 //
2629 // The credential providers had been collected before.
2630 //
2631 return EFI_SUCCESS;
2632 }
2633
2634 //
2635 // Try to find all the user credential provider driver.
2636 //
2637 HandleCount = 0;
2638 HandleBuf = NULL;
2639 Status = gBS->LocateHandleBuffer (
2640 ByProtocol,
2641 &gEfiUserCredential2ProtocolGuid,
2642 NULL,
2643 &HandleCount,
2644 &HandleBuf
2645 );
2646 if (EFI_ERROR (Status)) {
2647 return Status;
2648 }
2649
2650 //
2651 // Get provider infomation.
2652 //
2653 mProviderDb = AllocateZeroPool (
2654 sizeof (CREDENTIAL_PROVIDER_INFO) -
2655 sizeof (EFI_USER_CREDENTIAL2_PROTOCOL *) +
2656 HandleCount * sizeof (EFI_USER_CREDENTIAL2_PROTOCOL *)
2657 );
2658 if (mProviderDb == NULL) {
2659 FreePool (HandleBuf);
2660 return EFI_OUT_OF_RESOURCES;
2661 }
2662
2663 mProviderDb->Count = HandleCount;
2664 for (Index = 0; Index < HandleCount; Index++) {
2665 Status = gBS->HandleProtocol (
2666 HandleBuf[Index],
2667 &gEfiUserCredential2ProtocolGuid,
2668 (VOID **) &mProviderDb->Provider[Index]
2669 );
2670 if (EFI_ERROR (Status)) {
2671 FreePool (HandleBuf);
2672 FreePool (mProviderDb);
2673 mProviderDb = NULL;
2674 return Status;
2675 }
2676 }
2677
2678 FreePool (HandleBuf);
2679 return EFI_SUCCESS;
2680 }
2681
2682
2683 /**
2684 This function allows a caller to extract the current configuration for one
2685 or more named elements from the target driver.
2686
2687
2688 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
2689 @param Request A null-terminated Unicode string in <ConfigRequest> format.
2690 @param Progress On return, points to a character in the Request string.
2691 Points to the string's null terminator if request was successful.
2692 Points to the most recent '&' before the first failing name/value
2693 pair (or the beginning of the string if the failure is in the
2694 first name/value pair) if the request was not successful.
2695 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
2696 has all values filled in for the names in the Request string.
2697 String to be allocated by the called function.
2698
2699 @retval EFI_SUCCESS The Results is filled with the requested values.
2700 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
2701 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
2702 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
2703
2704 **/
2705 EFI_STATUS
2706 EFIAPI
2707 FakeExtractConfig (
2708 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
2709 IN CONST EFI_STRING Request,
2710 OUT EFI_STRING *Progress,
2711 OUT EFI_STRING *Results
2712 )
2713 {
2714 if (Progress == NULL || Results == NULL) {
2715 return EFI_INVALID_PARAMETER;
2716 }
2717 *Progress = Request;
2718 return EFI_NOT_FOUND;
2719 }
2720
2721 /**
2722 This function processes the results of changes in configuration.
2723
2724
2725 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
2726 @param Configuration A null-terminated Unicode string in <ConfigResp> format.
2727 @param Progress A pointer to a string filled in with the offset of the most
2728 recent '&' before the first failing name/value pair (or the
2729 beginning of the string if the failure is in the first
2730 name/value pair) or the terminating NULL if all was successful.
2731
2732 @retval EFI_SUCCESS The Results is processed successfully.
2733 @retval EFI_INVALID_PARAMETER Configuration is NULL.
2734 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
2735
2736 **/
2737 EFI_STATUS
2738 EFIAPI
2739 FakeRouteConfig (
2740 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
2741 IN CONST EFI_STRING Configuration,
2742 OUT EFI_STRING *Progress
2743 )
2744 {
2745 if (Configuration == NULL || Progress == NULL) {
2746 return EFI_INVALID_PARAMETER;
2747 }
2748
2749 return EFI_NOT_FOUND;
2750 }
2751
2752
2753 /**
2754 This function initialize the data mainly used in form browser.
2755
2756 @retval EFI_SUCCESS Initialize form data successfully.
2757 @retval Others Fail to Initialize form data.
2758
2759 **/
2760 EFI_STATUS
2761 InitFormBrowser (
2762 VOID
2763 )
2764 {
2765 EFI_STATUS Status;
2766 USER_MANAGER_CALLBACK_INFO *CallbackInfo;
2767 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
2768 EFI_HII_STRING_PROTOCOL *HiiString;
2769 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
2770
2771 //
2772 // Initialize driver private data.
2773 //
2774 CallbackInfo = AllocateZeroPool (sizeof (USER_MANAGER_CALLBACK_INFO));
2775 if (CallbackInfo == NULL) {
2776 return EFI_OUT_OF_RESOURCES;
2777 }
2778
2779 CallbackInfo->Signature = USER_MANAGER_SIGNATURE;
2780 CallbackInfo->ConfigAccess.ExtractConfig = FakeExtractConfig;
2781 CallbackInfo->ConfigAccess.RouteConfig = FakeRouteConfig;
2782 CallbackInfo->ConfigAccess.Callback = UserIdentifyManagerCallback;
2783
2784 //
2785 // Locate Hii Database protocol.
2786 //
2787 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
2788 if (EFI_ERROR (Status)) {
2789 return Status;
2790 }
2791 CallbackInfo->HiiDatabase = HiiDatabase;
2792
2793 //
2794 // Locate HiiString protocol.
2795 //
2796 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
2797 if (EFI_ERROR (Status)) {
2798 return Status;
2799 }
2800 CallbackInfo->HiiString = HiiString;
2801
2802 //
2803 // Locate Formbrowser2 protocol.
2804 //
2805 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
2806 if (EFI_ERROR (Status)) {
2807 return Status;
2808 }
2809
2810 CallbackInfo->FormBrowser2 = FormBrowser2;
2811 CallbackInfo->DriverHandle = NULL;
2812
2813 //
2814 // Install Device Path Protocol and Config Access protocol to driver handle.
2815 //
2816 Status = gBS->InstallMultipleProtocolInterfaces (
2817 &CallbackInfo->DriverHandle,
2818 &gEfiDevicePathProtocolGuid,
2819 &mHiiVendorDevicePath,
2820 &gEfiHiiConfigAccessProtocolGuid,
2821 &CallbackInfo->ConfigAccess,
2822 NULL
2823 );
2824 ASSERT_EFI_ERROR (Status);
2825
2826 //
2827 // Publish HII data.
2828 //
2829 CallbackInfo->HiiHandle = HiiAddPackages (
2830 &gUserIdentifyManagerGuid,
2831 CallbackInfo->DriverHandle,
2832 UserIdentifyManagerStrings,
2833 UserIdentifyManagerVfrBin,
2834 NULL
2835 );
2836 if (CallbackInfo->HiiHandle == NULL) {
2837 return EFI_OUT_OF_RESOURCES;
2838 }
2839
2840 mCallbackInfo = CallbackInfo;
2841
2842 return EFI_SUCCESS;
2843 }
2844
2845
2846 /**
2847 Identify the user whose identification policy supports auto logon.
2848
2849 @param[in] ProviderIndex The provider index in the provider list.
2850 @param[out] User Points to user user profile if a user is identified successfully.
2851
2852 @retval EFI_SUCCESS Identify a user with the specified provider successfully.
2853 @retval Others Fail to identify a user.
2854
2855 **/
2856 EFI_STATUS
2857 IdentifyAutoLogonUser (
2858 IN UINTN ProviderIndex,
2859 OUT USER_PROFILE_ENTRY **User
2860 )
2861 {
2862 EFI_STATUS Status;
2863 EFI_USER_INFO *Info;
2864 UINT8 PolicyType;
2865
2866 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER));
2867 if (Info == NULL) {
2868 return EFI_OUT_OF_RESOURCES;
2869 }
2870
2871 Info->InfoType = EFI_USER_INFO_IDENTIFIER_RECORD;
2872 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER);
2873
2874 //
2875 // Identify the specified credential provider's auto logon user.
2876 //
2877 Status = mProviderDb->Provider[ProviderIndex]->User (
2878 mProviderDb->Provider[ProviderIndex],
2879 NULL,
2880 (EFI_USER_INFO_IDENTIFIER *) (Info + 1)
2881 );
2882 if (EFI_ERROR (Status)) {
2883 FreePool (Info);
2884 return Status;
2885 }
2886
2887 //
2888 // Find user with the specified user ID.
2889 //
2890 *User = NULL;
2891 Status = FindUserProfileByInfo (User, NULL, Info, Info->InfoSize);
2892 FreePool (Info);
2893 if (EFI_ERROR (Status)) {
2894 return Status;
2895 }
2896
2897 Status = GetIdentifyType ((EFI_USER_PROFILE_HANDLE) * User, &PolicyType);
2898 if (PolicyType == EFI_USER_INFO_IDENTITY_AND) {
2899 //
2900 // The identified user need also identified by other credential provider.
2901 // This can handle through select user.
2902 //
2903 return EFI_NOT_READY;
2904 }
2905
2906 return Status;
2907 }
2908
2909
2910 /**
2911 Check whether the given console is ready.
2912
2913 @param[in] ProtocolGuid Points to the protocol guid of sonsole .
2914
2915 @retval TRUE The given console is ready.
2916 @retval FALSE The given console is not ready.
2917
2918 **/
2919 BOOLEAN
2920 CheckConsole (
2921 EFI_GUID *ProtocolGuid
2922 )
2923 {
2924 EFI_STATUS Status;
2925 UINTN HandleCount;
2926 EFI_HANDLE *HandleBuf;
2927 UINTN Index;
2928 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
2929
2930 //
2931 // Try to find all the handle driver.
2932 //
2933 HandleCount = 0;
2934 HandleBuf = NULL;
2935 Status = gBS->LocateHandleBuffer (
2936 ByProtocol,
2937 ProtocolGuid,
2938 NULL,
2939 &HandleCount,
2940 &HandleBuf
2941 );
2942 if (EFI_ERROR (Status)) {
2943 return FALSE;
2944 }
2945
2946 for (Index = 0; Index < HandleCount; Index++) {
2947 DevicePath = DevicePathFromHandle (HandleBuf[Index]);
2948 if (DevicePath != NULL) {
2949 FreePool (HandleBuf);
2950 return TRUE;
2951 }
2952 }
2953 FreePool (HandleBuf);
2954 return FALSE;
2955 }
2956
2957
2958 /**
2959 Check whether the console is ready.
2960
2961 @retval TRUE The console is ready.
2962 @retval FALSE The console is not ready.
2963
2964 **/
2965 BOOLEAN
2966 IsConsoleReady (
2967 VOID
2968 )
2969 {
2970 if (!CheckConsole (&gEfiSimpleTextOutProtocolGuid)) {
2971 return FALSE;
2972 }
2973
2974 if (!CheckConsole (&gEfiSimpleTextInProtocolGuid)) {
2975 if (!CheckConsole (&gEfiSimpleTextInputExProtocolGuid)) {
2976 return FALSE;
2977 }
2978 }
2979
2980 return TRUE;
2981 }
2982
2983
2984 /**
2985 Identify a user to logon.
2986
2987 @param[out] User Points to user user profile if a user is identified successfully.
2988
2989 @retval EFI_SUCCESS Identify a user successfully.
2990
2991 **/
2992 EFI_STATUS
2993 IdentifyUser (
2994 OUT USER_PROFILE_ENTRY **User
2995 )
2996 {
2997 EFI_STATUS Status;
2998 UINTN Index;
2999 EFI_CREDENTIAL_LOGON_FLAGS AutoLogon;
3000 EFI_USER_INFO *IdentifyInfo;
3001 EFI_USER_INFO_IDENTITY_POLICY *Identity;
3002 EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;
3003 USER_PROFILE_ENTRY *UserEntry;
3004
3005 //
3006 // Initialize credential providers.
3007 //
3008 InitProviderInfo ();
3009
3010 //
3011 // Initialize user profile database.
3012 //
3013 InitUserProfileDb ();
3014
3015 //
3016 // If only one user in system, and its identify policy is TRUE, then auto logon.
3017 //
3018 if (mUserProfileDb->UserProfileNum == 1) {
3019 UserEntry = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[0];
3020 IdentifyInfo = NULL;
3021 Status = FindUserInfoByType (UserEntry, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);
3022 if (EFI_ERROR (Status)) {
3023 return Status;
3024 }
3025 ASSERT (IdentifyInfo != NULL);
3026
3027 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1));
3028 if (Identity->Type == EFI_USER_INFO_IDENTITY_TRUE) {
3029 mCurrentUser = (EFI_USER_PROFILE_HANDLE) UserEntry;
3030 UpdateUserInfo (UserEntry);
3031 *User = UserEntry;
3032 return EFI_SUCCESS;
3033 }
3034 }
3035
3036 //
3037 // Find and login the default & AutoLogon user.
3038 //
3039 for (Index = 0; Index < mProviderDb->Count; Index++) {
3040 UserCredential = mProviderDb->Provider[Index];
3041 Status = UserCredential->Default (UserCredential, &AutoLogon);
3042 if (EFI_ERROR (Status)) {
3043 continue;
3044 }
3045
3046 if ((AutoLogon & (EFI_CREDENTIAL_LOGON_FLAG_DEFAULT | EFI_CREDENTIAL_LOGON_FLAG_AUTO)) != 0) {
3047 Status = IdentifyAutoLogonUser (Index, &UserEntry);
3048 if (Status == EFI_SUCCESS) {
3049 mCurrentUser = (EFI_USER_PROFILE_HANDLE) UserEntry;
3050 UpdateUserInfo (UserEntry);
3051 *User = UserEntry;
3052 return EFI_SUCCESS;
3053 }
3054 }
3055 }
3056
3057 if (!IsConsoleReady ()) {
3058 //
3059 // The console is still not ready for user selection.
3060 //
3061 return EFI_ACCESS_DENIED;
3062 }
3063
3064 //
3065 // Select a user and identify it.
3066 //
3067 mCallbackInfo->FormBrowser2->SendForm (
3068 mCallbackInfo->FormBrowser2,
3069 &mCallbackInfo->HiiHandle,
3070 1,
3071 &gUserIdentifyManagerGuid,
3072 0,
3073 NULL,
3074 NULL
3075 );
3076
3077 if (mIdentified) {
3078 *User = (USER_PROFILE_ENTRY *) mCurrentUser;
3079 UpdateUserInfo (*User);
3080 return EFI_SUCCESS;
3081 }
3082
3083 return EFI_ACCESS_DENIED;
3084 }
3085
3086
3087 /**
3088 An empty function to pass error checking of CreateEventEx ().
3089
3090 @param Event Event whose notification function is being invoked.
3091 @param Context Pointer to the notification function's context,
3092 which is implementation-dependent.
3093
3094 **/
3095 VOID
3096 EFIAPI
3097 InternalEmptyFuntion (
3098 IN EFI_EVENT Event,
3099 IN VOID *Context
3100 )
3101 {
3102 }
3103
3104
3105 /**
3106 Create, Signal, and Close the User Profile Changed event.
3107
3108 **/
3109 VOID
3110 SignalEventUserProfileChanged (
3111 VOID
3112 )
3113 {
3114 EFI_STATUS Status;
3115 EFI_EVENT Event;
3116
3117 Status = gBS->CreateEventEx (
3118 EVT_NOTIFY_SIGNAL,
3119 TPL_CALLBACK,
3120 InternalEmptyFuntion,
3121 NULL,
3122 &gEfiEventUserProfileChangedGuid,
3123 &Event
3124 );
3125 ASSERT_EFI_ERROR (Status);
3126 gBS->SignalEvent (Event);
3127 gBS->CloseEvent (Event);
3128 }
3129
3130
3131 /**
3132 Create a new user profile.
3133
3134 This function creates a new user profile with only a new user identifier attached and returns
3135 its handle. The user profile is non-volatile, but the handle User can change across reboots.
3136
3137 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3138 @param[out] User On return, points to the new user profile handle.
3139 The user profile handle is unique only during this boot.
3140
3141 @retval EFI_SUCCESS User profile was successfully created.
3142 @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to create a
3143 user profile.
3144 @retval EFI_UNSUPPORTED Creation of new user profiles is not supported.
3145 @retval EFI_INVALID_PARAMETER The User parameter is NULL.
3146
3147 **/
3148 EFI_STATUS
3149 EFIAPI
3150 UserProfileCreate (
3151 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3152 OUT EFI_USER_PROFILE_HANDLE *User
3153 )
3154 {
3155 EFI_STATUS Status;
3156
3157 if ((This == NULL) || (User == NULL)) {
3158 return EFI_INVALID_PARAMETER;
3159 }
3160
3161 //
3162 // Check the right of the current user.
3163 //
3164 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {
3165 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS)) {
3166 return EFI_ACCESS_DENIED;
3167 }
3168 }
3169
3170 //
3171 // Create new user profile
3172 //
3173 Status = CreateUserProfile ((USER_PROFILE_ENTRY **) User);
3174 if (EFI_ERROR (Status)) {
3175 return EFI_ACCESS_DENIED;
3176 }
3177 return EFI_SUCCESS;
3178 }
3179
3180
3181 /**
3182 Delete an existing user profile.
3183
3184 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3185 @param[in] User User profile handle.
3186
3187 @retval EFI_SUCCESS User profile was successfully deleted.
3188 @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to delete a user
3189 profile or there is only one user profile.
3190 @retval EFI_UNSUPPORTED Deletion of new user profiles is not supported.
3191 @retval EFI_INVALID_PARAMETER User does not refer to a valid user profile.
3192
3193 **/
3194 EFI_STATUS
3195 EFIAPI
3196 UserProfileDelete (
3197 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3198 IN EFI_USER_PROFILE_HANDLE User
3199 )
3200 {
3201 EFI_STATUS Status;
3202
3203 if (This == NULL) {
3204 return EFI_INVALID_PARAMETER;
3205 }
3206
3207 //
3208 // Check the right of the current user.
3209 //
3210 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {
3211 return EFI_ACCESS_DENIED;
3212 }
3213
3214 //
3215 // Delete user profile.
3216 //
3217 Status = DelUserProfile (User);
3218 if (EFI_ERROR (Status)) {
3219 if (Status != EFI_INVALID_PARAMETER) {
3220 return EFI_ACCESS_DENIED;
3221 }
3222 return EFI_INVALID_PARAMETER;
3223 }
3224
3225 return EFI_SUCCESS;
3226 }
3227
3228
3229 /**
3230 Enumerate all of the enrolled users on the platform.
3231
3232 This function returns the next enrolled user profile. To retrieve the first user profile handle,
3233 point User at a NULL. Each subsequent call will retrieve another user profile handle until there
3234 are no more, at which point User will point to NULL.
3235
3236 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3237 @param[in, out] User On entry, points to the previous user profile handle or NULL to
3238 start enumeration. On exit, points to the next user profile handle
3239 or NULL if there are no more user profiles.
3240
3241 @retval EFI_SUCCESS Next enrolled user profile successfully returned.
3242 @retval EFI_ACCESS_DENIED Next enrolled user profile was not successfully returned.
3243 @retval EFI_INVALID_PARAMETER The User parameter is NULL.
3244 **/
3245 EFI_STATUS
3246 EFIAPI
3247 UserProfileGetNext (
3248 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3249 IN OUT EFI_USER_PROFILE_HANDLE *User
3250 )
3251 {
3252 EFI_STATUS Status;
3253
3254 if ((This == NULL) || (User == NULL)) {
3255 return EFI_INVALID_PARAMETER;
3256 }
3257
3258 Status = FindUserProfile ((USER_PROFILE_ENTRY **) User, TRUE, NULL);
3259 if (EFI_ERROR (Status)) {
3260 return EFI_ACCESS_DENIED;
3261 }
3262 return EFI_SUCCESS;
3263 }
3264
3265
3266 /**
3267 Return the current user profile handle.
3268
3269 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3270 @param[out] CurrentUser On return, points to the current user profile handle.
3271
3272 @retval EFI_SUCCESS Current user profile handle returned successfully.
3273 @retval EFI_INVALID_PARAMETER The CurrentUser parameter is NULL.
3274
3275 **/
3276 EFI_STATUS
3277 EFIAPI
3278 UserProfileCurrent (
3279 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3280 OUT EFI_USER_PROFILE_HANDLE *CurrentUser
3281 )
3282 {
3283 //
3284 // Get current user profile.
3285 //
3286 if ((This == NULL) || (CurrentUser == NULL)) {
3287 return EFI_INVALID_PARAMETER;
3288 }
3289
3290 *CurrentUser = mCurrentUser;
3291 return EFI_SUCCESS;
3292 }
3293
3294
3295 /**
3296 Identify a user.
3297
3298 Identify the user and, if authenticated, returns the user handle and changes the current
3299 user profile. All user information marked as private in a previously selected profile
3300 is no longer available for inspection.
3301 Whenever the current user profile is changed then the an event with the GUID
3302 EFI_EVENT_GROUP_USER_PROFILE_CHANGED is signaled.
3303
3304 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3305 @param[out] User On return, points to the user profile handle for the current
3306 user profile.
3307
3308 @retval EFI_SUCCESS User was successfully identified.
3309 @retval EFI_ACCESS_DENIED User was not successfully identified.
3310 @retval EFI_INVALID_PARAMETER The User parameter is NULL.
3311
3312 **/
3313 EFI_STATUS
3314 EFIAPI
3315 UserProfileIdentify (
3316 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3317 OUT EFI_USER_PROFILE_HANDLE *User
3318 )
3319 {
3320 EFI_STATUS Status;
3321
3322 if ((This == NULL) || (User == NULL)) {
3323 return EFI_INVALID_PARAMETER;
3324 }
3325
3326 if (mCurrentUser != NULL) {
3327 *User = mCurrentUser;
3328 return EFI_SUCCESS;
3329 }
3330
3331 //
3332 // Identify user
3333 //
3334 Status = IdentifyUser ((USER_PROFILE_ENTRY **) User);
3335 if (EFI_ERROR (Status)) {
3336 return EFI_ACCESS_DENIED;
3337 }
3338
3339 //
3340 // Publish the user info into the EFI system configuration table.
3341 //
3342 PublishUserTable ();
3343
3344 //
3345 // Signal User Profile Changed event.
3346 //
3347 SignalEventUserProfileChanged ();
3348 return EFI_SUCCESS;
3349 }
3350
3351 /**
3352 Find a user using a user information record.
3353
3354 This function searches all user profiles for the specified user information record.
3355 The search starts with the user information record handle following UserInfo and
3356 continues until either the information is found or there are no more user profiles.
3357 A match occurs when the Info.InfoType field matches the user information record
3358 type and the user information record data matches the portion of Info.
3359
3360 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3361 @param[in, out] User On entry, points to the previously returned user profile
3362 handle, or NULL to start searching with the first user profile.
3363 On return, points to the user profile handle, or NULL if not
3364 found.
3365 @param[in, out] UserInfo On entry, points to the previously returned user information
3366 handle, or NULL to start searching with the first. On return,
3367 points to the user information handle of the user information
3368 record, or NULL if not found. Can be NULL, in which case only
3369 one user information record per user can be returned.
3370 @param[in] Info Points to the buffer containing the user information to be
3371 compared to the user information record. If the user information
3372 record data is empty, then only the user information record type
3373 is compared. If InfoSize is 0, then the user information record
3374 must be empty.
3375
3376 @param[in] InfoSize The size of Info, in bytes.
3377
3378 @retval EFI_SUCCESS User information was found. User points to the user profile
3379 handle, and UserInfo points to the user information handle.
3380 @retval EFI_NOT_FOUND User information was not found. User points to NULL, and
3381 UserInfo points to NULL.
3382 @retval EFI_INVALID_PARAMETER User is NULL. Or Info is NULL.
3383
3384 **/
3385 EFI_STATUS
3386 EFIAPI
3387 UserProfileFind (
3388 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3389 IN OUT EFI_USER_PROFILE_HANDLE *User,
3390 IN OUT EFI_USER_INFO_HANDLE *UserInfo OPTIONAL,
3391 IN CONST EFI_USER_INFO *Info,
3392 IN UINTN InfoSize
3393 )
3394 {
3395 EFI_STATUS Status;
3396 UINTN Size;
3397
3398 if ((This == NULL) || (User == NULL) || (Info == NULL)) {
3399 return EFI_INVALID_PARAMETER;
3400 }
3401
3402 if (InfoSize == 0) {
3403 //
3404 // If InfoSize is 0, then the user information record must be empty.
3405 //
3406 if (Info->InfoSize != sizeof (EFI_USER_INFO)) {
3407 return EFI_INVALID_PARAMETER;
3408 }
3409 } else {
3410 if (InfoSize != Info->InfoSize) {
3411 return EFI_INVALID_PARAMETER;
3412 }
3413 }
3414 Size = Info->InfoSize;
3415
3416 //
3417 // Find user profile accdoring to user information.
3418 //
3419 Status = FindUserProfileByInfo (
3420 (USER_PROFILE_ENTRY **) User,
3421 (EFI_USER_INFO **) UserInfo,
3422 (EFI_USER_INFO *) Info,
3423 Size
3424 );
3425 if (EFI_ERROR (Status)) {
3426 *User = NULL;
3427 if (UserInfo != NULL) {
3428 *UserInfo = NULL;
3429 }
3430 return EFI_NOT_FOUND;
3431 }
3432
3433 return EFI_SUCCESS;
3434 }
3435
3436
3437 /**
3438 Return information attached to the user.
3439
3440 This function returns user information. The format of the information is described in User
3441 Information. The function may return EFI_ACCESS_DENIED if the information is marked private
3442 and the handle specified by User is not the current user profile. The function may return
3443 EFI_ACCESS_DENIED if the information is marked protected and the information is associated
3444 with a credential provider for which the user has not been authenticated.
3445
3446 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3447 @param[in] User Handle of the user whose profile will be retrieved.
3448 @param[in] UserInfo Handle of the user information data record.
3449 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes. On exit,
3450 holds the user information. If the buffer is too small to hold the
3451 information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is
3452 updated to contain the number of bytes actually required.
3453 @param[in, out] InfoSize On entry, points to the size of Info. On return, points to the size
3454 of the user information.
3455
3456 @retval EFI_SUCCESS Information returned successfully.
3457 @retval EFI_ACCESS_DENIED The information about the specified user cannot be accessed by the
3458 current user.
3459 @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the
3460 returned data. The actual size required is returned in *InfoSize.
3461 @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not refer
3462 to a valid user info handle.
3463 @retval EFI_INVALID_PARAMETER Info is NULL or InfoSize is NULL.
3464
3465 **/
3466 EFI_STATUS
3467 EFIAPI
3468 UserProfileGetInfo (
3469 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3470 IN EFI_USER_PROFILE_HANDLE User,
3471 IN EFI_USER_INFO_HANDLE UserInfo,
3472 OUT EFI_USER_INFO *Info,
3473 IN OUT UINTN *InfoSize
3474 )
3475 {
3476 EFI_STATUS Status;
3477
3478 if ((This == NULL) || (InfoSize == NULL)) {
3479 return EFI_INVALID_PARAMETER;
3480 }
3481
3482 if ((*InfoSize != 0) && (Info == NULL)) {
3483 return EFI_INVALID_PARAMETER;
3484 }
3485
3486 if ((User == NULL) || (UserInfo == NULL)) {
3487 return EFI_NOT_FOUND;
3488 }
3489
3490 Status = GetUserInfo (User, UserInfo, Info, InfoSize, TRUE);
3491 if (EFI_ERROR (Status)) {
3492 if (Status == EFI_BUFFER_TOO_SMALL) {
3493 return EFI_BUFFER_TOO_SMALL;
3494 }
3495 return EFI_ACCESS_DENIED;
3496 }
3497 return EFI_SUCCESS;
3498 }
3499
3500
3501 /**
3502 Add or update user information.
3503
3504 This function changes user information. If NULL is pointed to by UserInfo, then a new user
3505 information record is created and its handle is returned in UserInfo. Otherwise, the existing
3506 one is replaced.
3507 If EFI_USER_INFO_IDENITTY_POLICY_RECORD is changed, it is the caller's responsibility to keep
3508 it to be synced with the information on credential providers.
3509 If EFI_USER_INFO_EXCLUSIVE is specified in Info and a user information record of the same
3510 type already exists in the user profile, then EFI_ACCESS_DENIED will be returned and UserInfo
3511 will point to the handle of the existing record.
3512
3513 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3514 @param[in] User Handle of the user whose profile will be retrieved.
3515 @param[in, out] UserInfo Handle of the user information data record.
3516 @param[in] Info On entry, points to a buffer of at least *InfoSize bytes. On exit,
3517 holds the user information. If the buffer is too small to hold the
3518 information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is
3519 updated to contain the number of bytes actually required.
3520 @param[in] InfoSize On entry, points to the size of Info. On return, points to the size
3521 of the user information.
3522
3523 @retval EFI_SUCCESS Information returned successfully.
3524 @retval EFI_ACCESS_DENIED The record is exclusive.
3525 @retval EFI_SECURITY_VIOLATION The current user does not have permission to change the specified
3526 user profile or user information record.
3527 @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not
3528 refer to a valid user info handle.
3529 @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL.
3530 **/
3531 EFI_STATUS
3532 EFIAPI
3533 UserProfileSetInfo (
3534 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3535 IN EFI_USER_PROFILE_HANDLE User,
3536 IN OUT EFI_USER_INFO_HANDLE *UserInfo,
3537 IN CONST EFI_USER_INFO *Info,
3538 IN UINTN InfoSize
3539 )
3540 {
3541 EFI_STATUS Status;
3542
3543 if ((This == NULL) || (User == NULL) || (UserInfo == NULL) || (Info == NULL)) {
3544 return EFI_INVALID_PARAMETER;
3545 }
3546
3547 //
3548 // Check the right of the current user.
3549 //
3550 if (User != mCurrentUser) {
3551 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {
3552 if (*UserInfo != NULL) {
3553 //
3554 // Can't update info in other profiles without MANAGE right.
3555 //
3556 return EFI_SECURITY_VIOLATION;
3557 }
3558
3559 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS)) {
3560 //
3561 // Can't add info into other profiles.
3562 //
3563 return EFI_SECURITY_VIOLATION;
3564 }
3565 }
3566 }
3567
3568 if (User == mCurrentUser) {
3569 if (CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_SELF)) {
3570 //
3571 // Only identify policy can be added/updated.
3572 //
3573 if (Info->InfoType != EFI_USER_INFO_IDENTITY_POLICY_RECORD) {
3574 return EFI_SECURITY_VIOLATION;
3575 }
3576 }
3577 }
3578
3579 //
3580 // Modify user information.
3581 //
3582 Status = ModifyUserInfo (User, (EFI_USER_INFO **) UserInfo, Info, InfoSize);
3583 if (EFI_ERROR (Status)) {
3584 if (Status == EFI_ACCESS_DENIED) {
3585 return EFI_ACCESS_DENIED;
3586 }
3587 return EFI_SECURITY_VIOLATION;
3588 }
3589 return EFI_SUCCESS;
3590 }
3591
3592
3593 /**
3594 Called by credential provider to notify of information change.
3595
3596 This function allows the credential provider to notify the User Identity Manager when user status
3597 has changed.
3598 If the User Identity Manager doesn't support asynchronous changes in credentials, then this function
3599 should return EFI_UNSUPPORTED.
3600 If current user does not exist, and the credential provider can identify a user, then make the user
3601 to be current user and signal the EFI_EVENT_GROUP_USER_PROFILE_CHANGED event.
3602 If current user already exists, and the credential provider can identify another user, then switch
3603 current user to the newly identified user, and signal the EFI_EVENT_GROUP_USER_PROFILE_CHANGED event.
3604 If current user was identified by this credential provider and now the credential provider cannot identify
3605 current user, then logout current user and signal the EFI_EVENT_GROUP_USER_PROFILE_CHANGED event.
3606
3607 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3608 @param[in] Changed Handle on which is installed an instance of the EFI_USER_CREDENTIAL2_PROTOCOL
3609 where the user has changed.
3610
3611 @retval EFI_SUCCESS The User Identity Manager has handled the notification.
3612 @retval EFI_NOT_READY The function was called while the specified credential provider was not selected.
3613 @retval EFI_UNSUPPORTED The User Identity Manager doesn't support asynchronous notifications.
3614
3615 **/
3616 EFI_STATUS
3617 EFIAPI
3618 UserProfileNotify (
3619 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3620 IN EFI_HANDLE Changed
3621 )
3622 {
3623 return EFI_UNSUPPORTED;
3624 }
3625
3626
3627 /**
3628 Delete user information.
3629
3630 Delete the user information attached to the user profile specified by the UserInfo.
3631
3632 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3633 @param[in] User Handle of the user whose information will be deleted.
3634 @param[in] UserInfo Handle of the user information to remove.
3635
3636 @retval EFI_SUCCESS User information deleted successfully.
3637 @retval EFI_NOT_FOUND User information record UserInfo does not exist in the user profile.
3638 @retval EFI_ACCESS_DENIED The current user does not have permission to delete this user information.
3639
3640 **/
3641 EFI_STATUS
3642 EFIAPI
3643 UserProfileDeleteInfo (
3644 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3645 IN EFI_USER_PROFILE_HANDLE User,
3646 IN EFI_USER_INFO_HANDLE UserInfo
3647 )
3648 {
3649 EFI_STATUS Status;
3650
3651 if (This == NULL) {
3652 return EFI_INVALID_PARAMETER;
3653 }
3654
3655 //
3656 // Check the right of the current user.
3657 //
3658 if (User != mCurrentUser) {
3659 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {
3660 return EFI_ACCESS_DENIED;
3661 }
3662 }
3663
3664 //
3665 // Delete user information.
3666 //
3667 Status = DelUserInfo (User, UserInfo, TRUE);
3668 if (EFI_ERROR (Status)) {
3669 if (Status == EFI_NOT_FOUND) {
3670 return EFI_NOT_FOUND;
3671 }
3672 return EFI_ACCESS_DENIED;
3673 }
3674 return EFI_SUCCESS;
3675 }
3676
3677
3678 /**
3679 Enumerate user information of all the enrolled users on the platform.
3680
3681 This function returns the next user information record. To retrieve the first user
3682 information record handle, point UserInfo at a NULL. Each subsequent call will retrieve
3683 another user information record handle until there are no more, at which point UserInfo
3684 will point to NULL.
3685
3686 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
3687 @param[in] User Handle of the user whose information will be deleted.
3688 @param[in, out] UserInfo Handle of the user information to remove.
3689
3690 @retval EFI_SUCCESS User information returned.
3691 @retval EFI_NOT_FOUND No more user information found.
3692 @retval EFI_INVALID_PARAMETER UserInfo is NULL.
3693
3694 **/
3695 EFI_STATUS
3696 EFIAPI
3697 UserProfileGetNextInfo (
3698 IN CONST EFI_USER_MANAGER_PROTOCOL *This,
3699 IN EFI_USER_PROFILE_HANDLE User,
3700 IN OUT EFI_USER_INFO_HANDLE *UserInfo
3701 )
3702 {
3703 if ((This == NULL) || (UserInfo == NULL)) {
3704 return EFI_INVALID_PARAMETER;
3705 }
3706 //
3707 // Get next user information entry.
3708 //
3709 return FindUserInfo (User, (EFI_USER_INFO **) UserInfo, TRUE, NULL);
3710 }
3711
3712
3713 /**
3714 Main entry for this driver.
3715
3716 @param[in] ImageHandle Image handle this driver.
3717 @param[in] SystemTable Pointer to SystemTable.
3718
3719 @retval EFI_SUCESS This function always complete successfully.
3720
3721 **/
3722 EFI_STATUS
3723 EFIAPI
3724 UserIdentifyManagerInit (
3725 IN EFI_HANDLE ImageHandle,
3726 IN EFI_SYSTEM_TABLE *SystemTable
3727 )
3728 {
3729
3730 EFI_STATUS Status;
3731
3732 //
3733 // Initiate form browser.
3734 //
3735 InitFormBrowser ();
3736
3737 //
3738 // Install protocol interfaces for the User Identity Manager.
3739 //
3740 Status = gBS->InstallProtocolInterface (
3741 &mCallbackInfo->DriverHandle,
3742 &gEfiUserManagerProtocolGuid,
3743 EFI_NATIVE_INTERFACE,
3744 &gUserIdentifyManager
3745 );
3746 ASSERT_EFI_ERROR (Status);
3747
3748 LoadDeferredImageInit (ImageHandle);
3749 return EFI_SUCCESS;
3750 }
3751
3752