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