]> 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
1019\r
1020 @retval EFI_SUCCESS Add or delete record successfully.\r
1021 @retval Others Fail to add or delete record.\r
1022\r
1023**/\r
1024EFI_STATUS\r
1025ModifyProviderCredential (\r
1026 IN EFI_GUID *Provider,\r
1027 IN BOOLEAN ByType,\r
1028 IN USER_PROFILE_ENTRY *User\r
1029 )\r
1030{\r
1031 UINTN Index;\r
1032 EFI_USER_CREDENTIAL_PROTOCOL *UserCredential;\r
1033 \r
1034 if (Provider == NULL) {\r
1035 return EFI_INVALID_PARAMETER;\r
1036 }\r
1037\r
1038 \r
1039 //\r
1040 // Find the specified credential provider.\r
1041 //\r
1042 for (Index = 0; Index < mProviderDb->Count; Index++) {\r
1043 //\r
1044 // Check credential provider ID.\r
1045 //\r
1046 UserCredential = mProviderDb->Provider[Index];\r
1047 if (CompareGuid (&UserCredential->Identifier, Provider)) {\r
1048 return UserCredential->Enroll (UserCredential, User);\r
1049 }\r
1050 }\r
1051\r
1052 return EFI_NOT_FOUND;\r
1053}\r
1054\r
1055\r
1056/**\r
1057 Modify user's credential record in the providers.\r
1058\r
1059 Found the providers information in PolicyInfo, and then add or delete the user's credential\r
1060 record in the providers.\r
1061\r
1062 @param User Points to user profile.\r
1063 @param PolicyInfo Point to identification policy to be modified.\r
1064 @param InfoLen The length of PolicyInfo.\r
1065\r
1066 @retval EFI_SUCCESS Modify PolicyInfo successfully.\r
1067 @retval Others Fail to modify PolicyInfo.\r
1068\r
1069**/\r
1070EFI_STATUS\r
1071ModifyCredentialInfo (\r
1072 IN USER_PROFILE_ENTRY *User,\r
1073 IN UINT8 *PolicyInfo,\r
1074 IN UINTN InfoLen\r
1075 )\r
1076{\r
1077 EFI_STATUS Status;\r
1078 UINTN TotalLen;\r
1079 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
1080\r
1081 //\r
1082 // Modify user's credential.\r
1083 //\r
1084 TotalLen = 0;\r
1085 while (TotalLen < InfoLen) {\r
1086 //\r
1087 // Check identification policy according to type.\r
1088 //\r
1089 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (PolicyInfo + TotalLen);\r
1090 switch (Identity->Type) {\r
1091 case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:\r
1092 Status = ModifyProviderCredential ((EFI_GUID *) (Identity + 1), TRUE, User);\r
1093 if (EFI_ERROR (Status)) {\r
1094 return Status;\r
1095 }\r
1096 break;\r
1097\r
1098 case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:\r
1099 Status = ModifyProviderCredential ((EFI_GUID *) (Identity + 1), FALSE, User);\r
1100 if (EFI_ERROR (Status)) {\r
1101 return Status;\r
1102 }\r
1103 break;\r
1104\r
1105 default:\r
1106 break;\r
1107 }\r
1108\r
1109 TotalLen += Identity->Length;\r
1110 }\r
1111\r
1112 return EFI_SUCCESS;\r
1113}\r
1114\r
1115\r
1116/**\r
1117 Save the user profile to non-volatile memory, or delete it from non-volatile memory.\r
1118\r
1119 @param[in] User Point to the user profile\r
1120 @param[in] Delete If TRUE, delete the found user profile.\r
1121 If FALSE, save the user profile.\r
1122 @retval EFI_SUCCESS Save or delete user profile successfully.\r
1123 @retval Others Fail to change the profile.\r
1124 \r
1125**/\r
1126EFI_STATUS\r
1127SaveNvUserProfile (\r
1128 IN USER_PROFILE_ENTRY *User,\r
1129 IN BOOLEAN Delete\r
1130 )\r
1131{\r
1132 EFI_STATUS Status;\r
1133\r
1134 //\r
1135 // Check user profile entry.\r
1136 //\r
1137 Status = FindUserProfile (&User, FALSE, NULL);\r
1138 if (EFI_ERROR (Status)) {\r
1139 return Status;\r
1140 }\r
1141 \r
1142 //\r
1143 // Save the user profile to non-volatile memory.\r
1144 //\r
1145 Status = gRT->SetVariable (\r
1146 User->UserVarName,\r
a0c56a82 1147 &gUserIdentifyManagerGuid,\r
0c18794e 1148 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1149 Delete ? 0 : User->UserProfileSize,\r
1150 User->ProfileInfo\r
1151 );\r
1152 return Status;\r
1153}\r
1154\r
1155\r
1156/**\r
1157 Replace the old identity info with NewInfo in NV Flash.\r
1158\r
1159 This function only replace the identity record in the user profile. Don't update\r
1160 the the information on the credential provider.\r
1161 \r
1162 @param[in] User Point to the user profile.\r
1163 @param[in] NewInfo Point to the new identity policy info.\r
1164 @param[out] UserInfo Point to the new added identity info.\r
1165\r
1166 @retval EFI_SUCCESS Replace user identity successfully.\r
1167 @retval Others Fail to Replace user identity.\r
1168\r
1169**/\r
1170EFI_STATUS\r
1171SaveUserIpInfo (\r
1172 IN USER_PROFILE_ENTRY * User,\r
1173 IN CONST EFI_USER_INFO * NewInfo,\r
1174 OUT EFI_USER_INFO **UserInfo OPTIONAL\r
1175 )\r
1176{\r
1177 EFI_STATUS Status;\r
1178 EFI_USER_INFO *OldIpInfo;\r
1179 UINTN Offset;\r
1180 UINTN NextOffset;\r
1181\r
1182 if ((NewInfo == NULL) || (User == NULL)) {\r
1183 return EFI_INVALID_PARAMETER;\r
1184 }\r
1185 \r
1186 //\r
1187 // Get user old identify policy information.\r
1188 //\r
1189 OldIpInfo = NULL;\r
1190 Status = FindUserInfoByType (User, &OldIpInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
1191 if (EFI_ERROR (Status)) {\r
1192 return Status;\r
1193 }\r
1194 \r
1195 //\r
1196 // Get the old identity policy offset.\r
1197 //\r
1198 Status = FindUserInfo (User, &OldIpInfo, FALSE, &Offset);\r
1199 if (EFI_ERROR (Status)) {\r
1200 return Status;\r
1201 }\r
1202 \r
1203 //\r
1204 // Delete the old identity policy information.\r
1205 //\r
1206 NextOffset = ALIGN_VARIABLE (OldIpInfo->InfoSize) + Offset;\r
1207 User->UserProfileSize -= ALIGN_VARIABLE (OldIpInfo->InfoSize);\r
1208 if (Offset < User->UserProfileSize) {\r
1209 CopyMem (User->ProfileInfo + Offset, User->ProfileInfo + NextOffset, User->UserProfileSize - Offset);\r
1210 }\r
1211 \r
1212 //\r
1213 // Add new user information.\r
1214 //\r
1215 if (User->MaxProfileSize - User->UserProfileSize < ALIGN_VARIABLE (NewInfo->InfoSize)) {\r
1216 if (!ExpandUserProfile (User, ALIGN_VARIABLE (NewInfo->InfoSize))) {\r
1217 return EFI_OUT_OF_RESOURCES;\r
1218 }\r
1219 }\r
1220\r
1221 CopyMem (User->ProfileInfo + User->UserProfileSize, (VOID *) NewInfo, NewInfo->InfoSize);\r
1222 if (UserInfo != NULL) {\r
1223 *UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + User->UserProfileSize);\r
1224 }\r
1225\r
1226 User->UserProfileSize += ALIGN_VARIABLE (NewInfo->InfoSize);\r
1227\r
1228 //\r
1229 // Save user profile information.\r
1230 //\r
1231 Status = SaveNvUserProfile (User, FALSE);\r
1232 return Status;\r
1233}\r
1234\r
1235\r
1236/**\r
1237 Remove the provider in FindIdentity from the user identification information record.\r
1238 \r
1239 @param[in, out] NewInfo On entry, points to the user information to remove provider. \r
1240 On return, points to the user information the provider is removed.\r
1241 @param[in] FindIdentity Point to the user identity policy.\r
1242\r
1243 @retval TRUE The provider is removed successfully.\r
1244 @retval FALSE Fail to remove the provider.\r
1245\r
1246**/\r
1247BOOLEAN\r
1248RemoveProvider (\r
1249 IN OUT EFI_USER_INFO **NewInfo,\r
1250 IN EFI_USER_INFO_IDENTITY_POLICY *FindIdentity\r
1251 )\r
1252{\r
1253 UINTN TotalLen;\r
1254 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
1255 EFI_USER_INFO *IdentifyInfo;\r
1256 UINT8 *Buffer;\r
1257\r
1258 IdentifyInfo = *NewInfo;\r
1259 TotalLen = IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO);\r
1260 if (TotalLen == FindIdentity->Length) {\r
1261 //\r
1262 // Only one credential provider in the identification policy.\r
1263 // Set the new policy to be TRUE after removed the provider.\r
1264 //\r
1265 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (IdentifyInfo + 1);\r
1266 Identity->Type = EFI_USER_INFO_IDENTITY_TRUE;\r
1267 Identity->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY); \r
1268 IdentifyInfo->InfoSize = sizeof (EFI_USER_INFO) + Identity->Length;\r
1269 return TRUE;\r
1270 }\r
1271\r
1272 //\r
1273 // Found the credential provider.\r
1274 //\r
1275 TotalLen = 0;\r
1276 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
1277 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
1278 if ((Identity->Type == FindIdentity->Type) &&\r
1279 (Identity->Length == FindIdentity->Length) &&\r
1280 CompareGuid ((EFI_GUID *) (Identity + 1), (EFI_GUID *) (FindIdentity + 1))\r
1281 ) {\r
1282 //\r
1283 // Found the credential provider to delete\r
1284 //\r
1285 if (Identity == (EFI_USER_INFO_IDENTITY_POLICY *)(IdentifyInfo + 1)) {\r
1286 //\r
1287 // It is the first item in the identification policy, delete it and the connector after it.\r
1288 //\r
1289 Buffer = (UINT8 *) Identity + Identity->Length + sizeof(EFI_USER_INFO_IDENTITY_POLICY);\r
1290 IdentifyInfo->InfoSize -= Identity->Length + sizeof(EFI_USER_INFO_IDENTITY_POLICY);\r
1291 TotalLen = IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO);\r
1292 CopyMem (Identity, Buffer, TotalLen);\r
1293 } else {\r
1294 //\r
1295 // It is not the first item in the identification policy, delete it and the connector before it.\r
1296 //\r
1297 Buffer = (UINT8 *) Identity + Identity->Length;\r
1298 TotalLen = IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO);\r
1299 TotalLen -= (Buffer - (UINT8 *)(IdentifyInfo + 1));\r
1300 IdentifyInfo->InfoSize -= Identity->Length + sizeof(EFI_USER_INFO_IDENTITY_POLICY);\r
1301 CopyMem ((UINT8 *) (Identity - 1), Buffer, TotalLen);\r
1302 } \r
1303 return TRUE;\r
1304 }\r
1305\r
1306 TotalLen += Identity->Length;\r
1307 } \r
1308 return FALSE;\r
1309}\r
1310\r
1311\r
1312/**\r
1313 This function replaces the old identity policy with a new identity policy.\r
1314\r
1315 This function changes user identity policy information.\r
1316 If enroll new credential failed, recover the old identity policy.\r
1317\r
1318 For new policy:\r
1319 a. For each credential, if it is newly added, try to enroll it.\r
1320 If enroll failed, try to delete the newly added ones.\r
1321 \r
1322 b. For each credential, if it exists in the old policy, delete old one, \r
1323 and enroll new one. If failed to enroll the new one, removed it from new \r
1324 identification policy.\r
1325\r
1326 For old policy: \r
1327 a. For each credential, if it does not exist in new one, delete it.\r
1328\r
1329 @param[in] User Point to the user profile.\r
1330 @param[in] Info Points to the user identity information.\r
1331 @param[in] InfoSize The size of Info (Not used in this function).\r
1332 @param[out] IpInfo The new identification info after modify.\r
1333\r
1334 @retval EFI_SUCCESS Modify user identity policy successfully.\r
1335 @retval Others Fail to modify user identity policy.\r
1336\r
1337**/\r
1338EFI_STATUS\r
1339ModifyUserIpInfo (\r
1340 IN USER_PROFILE_ENTRY *User,\r
1341 IN CONST EFI_USER_INFO *Info,\r
1342 IN UINTN InfoSize,\r
1343 OUT EFI_USER_INFO **IpInfo\r
1344 )\r
1345{\r
1346 EFI_STATUS Status;\r
1347 EFI_USER_INFO *OldIpInfo;\r
1348 UINTN TotalLen;\r
1349 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
1350 UINT32 CredentialCount;\r
1351 EFI_USER_INFO *NewIpInfo;\r
1352\r
1353 //\r
1354 // Get user old identify policy information.\r
1355 //\r
1356 OldIpInfo = NULL;\r
1357 Status = FindUserInfoByType (User, &OldIpInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
1358 if (EFI_ERROR (Status)) {\r
1359 return Status;\r
1360 }\r
1361 ASSERT (OldIpInfo != NULL);\r
1362 \r
1363 //\r
1364 // Enroll new added credential provider.\r
1365 //\r
1366 CredentialCount = 0;\r
1367 TotalLen = 0;\r
1368 while (TotalLen < Info->InfoSize - sizeof (EFI_USER_INFO)) {\r
1369 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (Info + 1) + TotalLen);\r
1370 if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
1371 if (!FindProvider (Identity, OldIpInfo)) {\r
1372 //\r
1373 // The credential is NOT found in the old identity policy; add it.\r
1374 //\r
1375 Status = ModifyCredentialInfo (User, (UINT8 *) Identity, Identity->Length);\r
1376 if (EFI_ERROR (Status)) {\r
1377 break;\r
1378 }\r
1379 CredentialCount++;\r
1380 }\r
1381 }\r
1382\r
1383 TotalLen += Identity->Length;\r
1384 }\r
1385\r
1386 if (EFI_ERROR (Status)) {\r
1387 //\r
1388 // Enroll new credential failed. Delete the newly enrolled credential, and return.\r
1389 //\r
1390 TotalLen = 0;\r
1391 while (TotalLen < Info->InfoSize - sizeof (EFI_USER_INFO)) {\r
1392 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (Info + 1) + TotalLen);\r
1393 if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
1394 if (!FindProvider (Identity, OldIpInfo)) {\r
1395 //\r
1396 // The credential is NOT found in the old identity policy. Delete it.\r
1397 //\r
1398 if (CredentialCount == 0) {\r
1399 break;\r
1400 }\r
1401\r
1402 ModifyCredentialInfo (User, (UINT8 *) Identity, Identity->Length);\r
1403 CredentialCount--;\r
1404 }\r
1405 }\r
1406 TotalLen += Identity->Length;\r
1407 }\r
1408\r
1409 return EFI_DEVICE_ERROR;\r
1410 }\r
1411 \r
1412 //\r
1413 // Backup new identification policy\r
1414 //\r
1415 NewIpInfo = AllocateCopyPool (Info->InfoSize, Info); \r
1416 ASSERT (NewIpInfo != NULL);\r
1417\r
1418 //\r
1419 // Enroll the credential that existed in the old identity policy.\r
1420 //\r
1421 TotalLen = 0;\r
1422 while (TotalLen < Info->InfoSize - sizeof (EFI_USER_INFO)) {\r
1423 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (Info + 1) + TotalLen);\r
1424 if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
1425 if (FindProvider (Identity, OldIpInfo)) {\r
1426 //\r
1427 // The credential is found in the old identity policy, so delete the old credential first.\r
1428 //\r
1429 Status = ModifyCredentialInfo (User, (UINT8 *) Identity, Identity->Length);\r
1430 if (EFI_ERROR (Status)) {\r
1431 //\r
1432 // Failed to delete old credential.\r
1433 //\r
1434 FreePool (NewIpInfo);\r
1435 return EFI_DEVICE_ERROR;\r
1436 }\r
1437\r
1438 //\r
1439 // Add the new credential.\r
1440 //\r
1441 Status = ModifyCredentialInfo (User, (UINT8 *) Identity, Identity->Length);\r
1442 if (EFI_ERROR (Status)) {\r
1443 //\r
1444 // Failed to enroll the user by new identification policy.\r
1445 // So removed the credential provider from the identification policy \r
1446 //\r
1447 RemoveProvider (&NewIpInfo, Identity);\r
1448 } \r
1449 }\r
1450 }\r
1451 TotalLen += Identity->Length;\r
1452 }\r
1453 \r
1454 //\r
1455 // Delete old credential that didn't exist in the new identity policy.\r
1456 //\r
1457 TotalLen = 0;\r
1458 while (TotalLen < OldIpInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
1459 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (OldIpInfo + 1) + TotalLen);\r
1460 if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
1461 if (!FindProvider (Identity, Info)) {\r
1462 //\r
1463 // The credential is NOT found in the new identity policy. Delete the old credential.\r
1464 //\r
1465 ModifyCredentialInfo (User, (UINT8 *) Identity, Identity->Length);\r
1466 }\r
1467 }\r
1468 TotalLen += Identity->Length;\r
1469 }\r
1470\r
1471 *IpInfo = NewIpInfo;\r
1472 return EFI_SUCCESS;\r
1473}\r
1474\r
1475\r
1476/**\r
1477 Add one new user info into the user's profile.\r
1478\r
1479 @param[in] User point to the user profile\r
1480 @param[in] Info Points to the user information payload.\r
1481 @param[in] InfoSize The size of the user information payload, in bytes.\r
1482 @param[out] UserInfo Point to the new info in user profile\r
1483 @param[in] Save If TRUE, save the profile to NV flash.\r
1484 If FALSE, don't need to save the profile to NV flash.\r
1485\r
1486 @retval EFI_SUCCESS Add user info to user profile successfully.\r
1487 @retval Others Fail to add user info to user profile.\r
1488\r
1489**/\r
1490EFI_STATUS\r
1491AddUserInfo (\r
1492 IN USER_PROFILE_ENTRY *User,\r
1493 IN UINT8 *Info,\r
1494 IN UINTN InfoSize,\r
1495 OUT EFI_USER_INFO **UserInfo, OPTIONAL\r
1496 IN BOOLEAN Save\r
1497 )\r
1498{\r
1499 EFI_STATUS Status;\r
1500\r
1501 if ((Info == NULL) || (User == NULL)) {\r
1502 return EFI_INVALID_PARAMETER;\r
1503 }\r
1504 \r
1505 //\r
1506 // Check user profile handle.\r
1507 //\r
1508 Status = FindUserProfile (&User, FALSE, NULL);\r
1509 if (EFI_ERROR (Status)) {\r
1510 return Status;\r
1511 }\r
1512 \r
1513 //\r
1514 // Check user information memory size.\r
1515 //\r
1516 if (User->MaxProfileSize - User->UserProfileSize < ALIGN_VARIABLE (InfoSize)) {\r
1517 if (!ExpandUserProfile (User, ALIGN_VARIABLE (InfoSize))) {\r
1518 return EFI_OUT_OF_RESOURCES;\r
1519 }\r
1520 }\r
1521 \r
1522 //\r
1523 // Add credential.\r
1524 //\r
1525 if (((EFI_USER_INFO *) Info)->InfoType == EFI_USER_INFO_IDENTITY_POLICY_RECORD) {\r
1526 Status = ModifyCredentialInfo (\r
1527 User,\r
1528 (UINT8 *) ((EFI_USER_INFO *) Info + 1),\r
1529 InfoSize - sizeof (EFI_USER_INFO)\r
1530 );\r
1531 if (EFI_ERROR (Status)) {\r
1532 return Status;\r
1533 }\r
1534 }\r
1535 \r
1536 //\r
1537 // Add new user information.\r
1538 //\r
1539 CopyMem (User->ProfileInfo + User->UserProfileSize, Info, InfoSize);\r
1540 if (UserInfo != NULL) {\r
1541 *UserInfo = (EFI_USER_INFO *) (User->ProfileInfo + User->UserProfileSize);\r
1542 }\r
1543 User->UserProfileSize += ALIGN_VARIABLE (InfoSize);\r
1544\r
1545 //\r
1546 // Save user profile information.\r
1547 //\r
1548 if (Save) {\r
1549 Status = SaveNvUserProfile (User, FALSE);\r
1550 }\r
1551\r
1552 return Status;\r
1553}\r
1554\r
1555\r
1556/**\r
1557 Get the user info from the specified user info handle.\r
1558\r
1559 @param[in] User Point to the user profile.\r
1560 @param[in] UserInfo Point to the user information record to get.\r
1561 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes. \r
1562 On exit, holds the user information.\r
1563 @param[in, out] InfoSize On entry, points to the size of Info. \r
1564 On return, points to the size of the user information.\r
1565 @param[in] ChkRight If TRUE, check the user info attribute.\r
1566 If FALSE, don't check the user info attribute.\r
1567\r
1568\r
1569 @retval EFI_ACCESS_DENIED The information cannot be accessed by the current user.\r
1570 @retval EFI_INVALID_PARAMETER InfoSize is NULL or UserInfo is NULL.\r
1571 @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the \r
1572 returned data. The actual size required is returned in *InfoSize.\r
1573 @retval EFI_SUCCESS Information returned successfully.\r
1574\r
1575**/\r
1576EFI_STATUS\r
1577GetUserInfo (\r
1578 IN USER_PROFILE_ENTRY *User,\r
1579 IN EFI_USER_INFO *UserInfo,\r
1580 OUT EFI_USER_INFO *Info,\r
1581 IN OUT UINTN *InfoSize,\r
1582 IN BOOLEAN ChkRight\r
1583 )\r
1584{\r
1585 EFI_STATUS Status;\r
1586\r
1587 if ((InfoSize == NULL) || (UserInfo == NULL)) {\r
1588 return EFI_INVALID_PARAMETER;\r
1589 }\r
1590\r
1591 if ((*InfoSize != 0) && (Info == NULL)) {\r
1592 return EFI_INVALID_PARAMETER;\r
1593 }\r
1594 \r
1595 //\r
1596 // Find the user information to get.\r
1597 //\r
1598 Status = FindUserInfo (User, &UserInfo, FALSE, NULL);\r
1599 if (EFI_ERROR (Status)) {\r
1600 return Status;\r
1601 }\r
1602 \r
1603 //\r
1604 // Check information attributes.\r
1605 //\r
1606 if (ChkRight) {\r
1607 switch (UserInfo->InfoAttribs & EFI_USER_INFO_ACCESS) {\r
1608 case EFI_USER_INFO_PRIVATE:\r
1609 case EFI_USER_INFO_PROTECTED:\r
1610 if (User != mCurrentUser) {\r
1611 return EFI_ACCESS_DENIED;\r
1612 }\r
1613 break;\r
1614\r
1615 case EFI_USER_INFO_PUBLIC:\r
1616 break;\r
1617\r
1618 default:\r
1619 return EFI_INVALID_PARAMETER;\r
1620 break;\r
1621 }\r
1622 }\r
1623 \r
1624 //\r
1625 // Get user information.\r
1626 //\r
1627 if (UserInfo->InfoSize > *InfoSize) {\r
1628 *InfoSize = UserInfo->InfoSize;\r
1629 return EFI_BUFFER_TOO_SMALL;\r
1630 }\r
1631\r
1632 *InfoSize = UserInfo->InfoSize;\r
1633 if (Info != NULL) {\r
1634 CopyMem (Info, UserInfo, *InfoSize);\r
1635 }\r
1636\r
1637 return EFI_SUCCESS;\r
1638}\r
1639\r
1640\r
1641/**\r
1642 Delete the specified user information from user profile.\r
1643\r
1644 @param[in] User Point to the user profile.\r
1645 @param[in] Info Point to the user information record to delete.\r
1646 @param[in] Save If TRUE, save the profile to NV flash.\r
1647 If FALSE, don't need to save the profile to NV flash.\r
1648\r
1649 @retval EFI_SUCCESS Delete user info from user profile successfully.\r
1650 @retval Others Fail to delete user info from user profile.\r
1651\r
1652**/\r
1653EFI_STATUS\r
1654DelUserInfo (\r
1655 IN USER_PROFILE_ENTRY *User,\r
1656 IN EFI_USER_INFO *Info,\r
1657 IN BOOLEAN Save\r
1658 )\r
1659{\r
1660 EFI_STATUS Status;\r
1661 UINTN Offset;\r
1662 UINTN NextOffset;\r
1663\r
1664 //\r
1665 // Check user information handle.\r
1666 //\r
1667 Status = FindUserInfo (User, &Info, FALSE, &Offset);\r
1668 if (EFI_ERROR (Status)) {\r
1669 return Status;\r
1670 }\r
1671\r
1672 if (Info->InfoType == EFI_USER_INFO_IDENTIFIER_RECORD) {\r
1673 return EFI_ACCESS_DENIED;\r
1674 } else if (Info->InfoType == EFI_USER_INFO_IDENTITY_POLICY_RECORD) {\r
1675 Status = ModifyCredentialInfo (User, (UINT8 *) (Info + 1), Info->InfoSize - sizeof (EFI_USER_INFO));\r
1676 if (EFI_ERROR (Status)) {\r
1677 return Status;\r
1678 }\r
1679 }\r
1680 \r
1681 //\r
1682 // Delete the specified user information.\r
1683 //\r
1684 NextOffset = Offset + ALIGN_VARIABLE (Info->InfoSize);\r
1685 User->UserProfileSize -= ALIGN_VARIABLE (Info->InfoSize);\r
1686 if (Offset < User->UserProfileSize) {\r
1687 CopyMem (User->ProfileInfo + Offset, User->ProfileInfo + NextOffset, User->UserProfileSize - Offset);\r
1688 }\r
1689\r
1690 if (Save) {\r
1691 Status = SaveNvUserProfile (User, FALSE);\r
1692 }\r
1693\r
1694 return Status;\r
1695}\r
1696\r
1697\r
1698/**\r
1699 Add or update user information.\r
1700\r
1701 @param[in] User Point to the user profile.\r
1702 @param[in, out] UserInfo On entry, points to the user information to modify,\r
1703 or NULL to add a new UserInfo. \r
1704 On return, points to the modified user information.\r
1705 @param[in] Info Points to the new user information.\r
1706 @param[in] InfoSize The size of Info,in bytes.\r
1707\r
1708 @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL.\r
1709 @retval EFI_ACCESS_DENIED The record is exclusive.\r
1710 @retval EFI_SUCCESS User information was successfully changed/added.\r
1711\r
1712**/\r
1713EFI_STATUS\r
1714ModifyUserInfo (\r
1715 IN USER_PROFILE_ENTRY *User,\r
1716 IN OUT EFI_USER_INFO **UserInfo,\r
1717 IN CONST EFI_USER_INFO *Info,\r
1718 IN UINTN InfoSize\r
1719 )\r
1720{\r
1721 EFI_STATUS Status;\r
1722 UINTN PayloadLen;\r
1723 EFI_USER_INFO *OldInfo;\r
1724 EFI_USER_INFO *IpInfo;\r
1725\r
1726 if ((UserInfo == NULL) || (Info == NULL)) {\r
1727 return EFI_INVALID_PARAMETER;\r
1728 }\r
1729\r
1730 if (InfoSize < sizeof (EFI_USER_INFO) || InfoSize != Info->InfoSize) {\r
1731 return EFI_INVALID_PARAMETER;\r
1732 }\r
1733 \r
1734 //\r
1735 // Check user information.\r
1736 //\r
1737 if (Info->InfoType == EFI_USER_INFO_IDENTIFIER_RECORD) {\r
1738 return EFI_ACCESS_DENIED;\r
1739 }\r
1740 \r
1741 if (!CheckUserInfo (Info)) {\r
1742 return EFI_INVALID_PARAMETER;\r
1743 }\r
1744\r
1745\r
1746 if (*UserInfo == NULL) {\r
1747 //\r
1748 // Add new user information.\r
1749 //\r
1750 OldInfo = NULL;\r
1751 do {\r
1752 Status = FindUserInfoByType (User, &OldInfo, Info->InfoType);\r
1753 if (EFI_ERROR (Status)) {\r
1754 break;\r
1755 }\r
1756 ASSERT (OldInfo != NULL);\r
1757\r
1758 if (((OldInfo->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0) || \r
1759 ((Info->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0)) {\r
1760 //\r
1761 // Same type can not co-exist for exclusive information.\r
1762 //\r
1763 return EFI_ACCESS_DENIED;\r
1764 }\r
1765\r
1766 //\r
1767 // Check whether it exists in DB.\r
1768 //\r
1769 if (Info->InfoSize != OldInfo->InfoSize) {\r
1770 continue;\r
1771 }\r
1772\r
1773 if (!CompareGuid (&OldInfo->Credential, &Info->Credential)) {\r
1774 continue;\r
1775 }\r
1776 \r
1777 PayloadLen = Info->InfoSize - sizeof (EFI_USER_INFO);\r
1778 if (PayloadLen == 0) {\r
1779 continue;\r
1780 }\r
1781\r
1782 if (CompareMem ((UINT8 *)(OldInfo + 1), (UINT8 *)(Info + 1), PayloadLen) != 0) {\r
1783 continue;\r
1784 }\r
1785\r
1786 //\r
1787 // Yes. The new info is as same as the one in profile.\r
1788 //\r
1789 return EFI_SUCCESS;\r
1790 } while (!EFI_ERROR (Status));\r
1791\r
1792 Status = AddUserInfo (User, (UINT8 *) Info, InfoSize, UserInfo, TRUE);\r
1793 return Status;\r
1794 }\r
1795 \r
1796 //\r
1797 // Modify existing user information.\r
1798 //\r
1799 OldInfo = *UserInfo;\r
1800 if (OldInfo->InfoType != Info->InfoType) {\r
1801 return EFI_INVALID_PARAMETER;\r
1802 }\r
1803 \r
1804 if (((Info->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) != 0) && \r
1805 (OldInfo->InfoAttribs & EFI_USER_INFO_EXCLUSIVE) == 0) {\r
1806 //\r
1807 // Try to add exclusive attrib in new info. \r
1808 // Check whether there is another information with the same type in profile.\r
1809 //\r
1810 OldInfo = NULL;\r
1811 do {\r
1812 Status = FindUserInfoByType (User, &OldInfo, Info->InfoType);\r
1813 if (EFI_ERROR (Status)) {\r
1814 break;\r
1815 }\r
1816 if (OldInfo != *UserInfo) {\r
1817 //\r
1818 // There is another information with the same type in profile.\r
1819 // Therefore, can't modify existing user information to add exclusive attribute.\r
1820 //\r
1821 return EFI_ACCESS_DENIED;\r
1822 }\r
1823 } while (TRUE); \r
1824 }\r
1825\r
1826 if (Info->InfoType == EFI_USER_INFO_IDENTITY_POLICY_RECORD) {\r
1827 //\r
1828 // For user identification policy, need to update the info in credential provider.\r
1829 //\r
1830 IpInfo = NULL;\r
1831 Status = ModifyUserIpInfo (User, Info, InfoSize, &IpInfo);\r
1832 if (EFI_ERROR (Status)) {\r
1833 return Status;\r
1834 }\r
1835\r
1836 ASSERT (IpInfo != NULL);\r
1837 Status = SaveUserIpInfo (User, IpInfo, UserInfo);\r
1838 if (IpInfo->InfoSize != Info->InfoSize) {\r
1839 Status = EFI_DEVICE_ERROR;\r
1840 }\r
1841 FreePool (IpInfo); \r
1842 return Status;\r
1843 }\r
1844\r
1845 Status = DelUserInfo (User, *UserInfo, FALSE);\r
1846 if (EFI_ERROR (Status)) {\r
1847 return Status;\r
1848 }\r
1849\r
1850 return AddUserInfo (User, (UINT8 *) Info, InfoSize, UserInfo, TRUE);\r
1851}\r
1852\r
1853\r
1854/**\r
1855 Delete the user profile from non-volatile memory and database.\r
1856\r
1857 @param[in] User Points to the user profile.\r
1858\r
1859 @retval EFI_SUCCESS Delete user from the user profile successfully.\r
1860 @retval Others Fail to delete user from user profile\r
1861 \r
1862**/\r
1863EFI_STATUS\r
1864DelUserProfile (\r
1865 IN USER_PROFILE_ENTRY *User\r
1866 )\r
1867{\r
1868 EFI_STATUS Status;\r
1869 UINTN Index;\r
1870 EFI_USER_INFO *UserInfo;\r
1871\r
1872 //\r
1873 // Check whether it is in the user profile database.\r
1874 //\r
1875 Status = FindUserProfile (&User, FALSE, &Index);\r
1876 if (EFI_ERROR (Status)) {\r
1877 return EFI_INVALID_PARAMETER;\r
1878 }\r
1879 \r
1880 //\r
1881 // Check whether it is the current user.\r
1882 //\r
1883 if (User == mCurrentUser) {\r
1884 return EFI_ACCESS_DENIED;\r
1885 }\r
1886 \r
1887 //\r
1888 // Delete user credential information.\r
1889 //\r
1890 UserInfo = NULL;\r
1891 Status = FindUserInfoByType (User, &UserInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
1892 if (Status == EFI_SUCCESS) {\r
1893 Status = DelUserInfo (User, UserInfo, FALSE);\r
1894 if (EFI_ERROR (Status)) {\r
1895 return Status;\r
1896 }\r
1897 }\r
1898 \r
1899 //\r
1900 // Delete user profile from the non-volatile memory.\r
1901 //\r
1902 Status = SaveNvUserProfile (mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum - 1], TRUE);\r
1903 if (EFI_ERROR (Status)) {\r
1904 return Status;\r
1905 }\r
1906 mUserProfileDb->UserProfileNum--;\r
1907\r
1908 //\r
1909 // Modify user profile database.\r
1910 //\r
1911 if (Index != mUserProfileDb->UserProfileNum) {\r
1912 mUserProfileDb->UserProfile[Index] = mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum];\r
1913 CopyMem (\r
1914 ((USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[Index])->UserVarName,\r
1915 User->UserVarName,\r
1916 sizeof (User->UserVarName)\r
1917 );\r
1918 Status = SaveNvUserProfile (mUserProfileDb->UserProfile[Index], FALSE);\r
1919 if (EFI_ERROR (Status)) {\r
1920 return Status;\r
1921 }\r
1922 }\r
1923 //\r
1924 // Delete user profile information.\r
1925 //\r
1926 if (User->ProfileInfo != NULL) {\r
1927 FreePool (User->ProfileInfo);\r
1928 }\r
1929\r
1930 FreePool (User);\r
1931 return EFI_SUCCESS;\r
1932}\r
1933\r
1934\r
1935/**\r
1936 Add user profile to user profile database.\r
1937\r
1938 @param[out] UserProfile Point to the newly added user profile.\r
1939 @param[in] ProfileSize The size of the user profile.\r
1940 @param[in] ProfileInfo Point to the user profie data.\r
1941 @param[in] Save If TRUE, save the new added profile to NV flash.\r
1942 If FALSE, don't save the profile to NV flash.\r
1943\r
1944 @retval EFI_SUCCESS Add user profile to user profile database successfully.\r
1945 @retval Others Fail to add user profile to user profile database.\r
1946\r
1947**/\r
1948EFI_STATUS\r
1949AddUserProfile (\r
1950 OUT USER_PROFILE_ENTRY **UserProfile, OPTIONAL\r
1951 IN UINTN ProfileSize,\r
1952 IN UINT8 *ProfileInfo,\r
1953 IN BOOLEAN Save\r
1954 )\r
1955{\r
1956 EFI_STATUS Status;\r
1957 USER_PROFILE_ENTRY *User;\r
1958\r
1959 //\r
1960 // Check the data format to be added.\r
1961 //\r
1962 if (!CheckProfileInfo (ProfileInfo, ProfileSize)) {\r
1963 return EFI_SECURITY_VIOLATION;\r
1964 }\r
1965 \r
1966 //\r
1967 // Create user profile entry.\r
1968 //\r
1969 User = AllocateZeroPool (sizeof (USER_PROFILE_ENTRY));\r
1970 if (User == NULL) {\r
1971 return EFI_OUT_OF_RESOURCES;\r
1972 }\r
1973 //\r
1974 // Add the entry to the user profile database.\r
1975 //\r
1976 if (mUserProfileDb->UserProfileNum == mUserProfileDb->MaxProfileNum) {\r
1977 if (!ExpandUsermUserProfileDb ()) {\r
1978 FreePool (User);\r
1979 return EFI_OUT_OF_RESOURCES;\r
1980 }\r
1981 }\r
1982\r
1983 UnicodeSPrint (\r
1984 User->UserVarName, \r
1985 sizeof (User->UserVarName),\r
1986 L"User%04x", \r
1987 mUserProfileDb->UserProfileNum\r
1988 );\r
1989 User->UserProfileSize = 0;\r
1990 User->MaxProfileSize = 0;\r
1991 User->ProfileInfo = NULL;\r
1992 mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum] = (EFI_USER_PROFILE_HANDLE) User;\r
1993 mUserProfileDb->UserProfileNum++;\r
1994\r
1995 //\r
1996 // Add user profile information.\r
1997 //\r
1998 Status = AddUserInfo (User, ProfileInfo, ProfileSize, NULL, Save);\r
1999 if (EFI_ERROR (Status)) {\r
2000 DelUserProfile (User);\r
2001 return Status;\r
2002 }\r
2003 //\r
2004 // Set new user profile handle.\r
2005 //\r
2006 if (UserProfile != NULL) {\r
2007 *UserProfile = User;\r
2008 }\r
2009\r
2010 return EFI_SUCCESS;\r
2011}\r
2012\r
2013\r
2014/**\r
2015 This function creates a new user profile with only a new user identifier\r
2016 attached and returns its handle. The user profile is non-volatile, but the\r
2017 handle User can change across reboots.\r
2018\r
2019 @param[out] User Handle of a new user profile.\r
2020\r
2021 @retval EFI_SUCCESS User profile was successfully created.\r
2022 @retval Others Fail to create user profile\r
2023\r
2024**/\r
2025EFI_STATUS\r
2026CreateUserProfile (\r
2027 OUT USER_PROFILE_ENTRY **User\r
2028 )\r
2029{\r
2030 EFI_STATUS Status;\r
2031 EFI_USER_INFO *UserInfo;\r
2032\r
2033 if (User == NULL) {\r
2034 return EFI_INVALID_PARAMETER;\r
2035 }\r
2036 //\r
2037 // Generate user id information.\r
2038 //\r
2039 UserInfo = AllocateZeroPool (sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER));\r
2040 if (UserInfo == NULL) {\r
2041 return EFI_OUT_OF_RESOURCES;\r
2042 }\r
2043\r
2044 UserInfo->InfoType = EFI_USER_INFO_IDENTIFIER_RECORD;\r
2045 UserInfo->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER);\r
2046 UserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2047 GenerateUserId ((UINT8 *) (UserInfo + 1));\r
2048 \r
2049 //\r
2050 // Add user profile to the user profile database.\r
2051 //\r
2052 Status = AddUserProfile (User, UserInfo->InfoSize, (UINT8 *) UserInfo, TRUE);\r
2053 FreePool (UserInfo);\r
2054 return Status;\r
2055}\r
2056\r
2057\r
2058/**\r
2059 Add a default user profile to user profile database.\r
2060\r
2061 @retval EFI_SUCCESS A default user profile is added successfully.\r
2062 @retval Others Fail to add a default user profile\r
2063 \r
2064**/\r
2065EFI_STATUS\r
2066AddDefaultUserProfile (\r
2067 VOID\r
2068 )\r
2069{\r
2070 EFI_STATUS Status;\r
2071 USER_PROFILE_ENTRY *User;\r
2072 EFI_USER_INFO *Info;\r
2073 EFI_USER_INFO *NewInfo;\r
2074 EFI_USER_INFO_CREATE_DATE CreateDate;\r
2075 EFI_USER_INFO_USAGE_COUNT UsageCount;\r
2076 EFI_USER_INFO_ACCESS_CONTROL *Access;\r
2077 EFI_USER_INFO_IDENTITY_POLICY *Policy;\r
2078 \r
2079 //\r
2080 // Create a user profile.\r
2081 //\r
2082 Status = CreateUserProfile (&User);\r
2083 if (EFI_ERROR (Status)) {\r
2084 return Status;\r
2085 }\r
2086 \r
2087 //\r
2088 // Allocate a buffer to add all default user information.\r
2089 //\r
2090 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + INFO_PAYLOAD_SIZE);\r
2091 if (Info == NULL) {\r
2092 return EFI_OUT_OF_RESOURCES;\r
2093 }\r
2094\r
2095 //\r
2096 // Add user name.\r
2097 //\r
2098 Info->InfoType = EFI_USER_INFO_NAME_RECORD;\r
2099 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2100 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (mUserName);\r
2101 CopyMem ((UINT8 *) (Info + 1), mUserName, sizeof (mUserName));\r
2102 NewInfo = NULL;\r
2103 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2104 if (EFI_ERROR (Status)) {\r
2105 goto Done;\r
2106 }\r
2107 \r
2108 //\r
2109 // Add user profile create date record.\r
2110 //\r
2111 Info->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD;\r
2112 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2113 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE);\r
2114 Status = gRT->GetTime (&CreateDate, NULL);\r
2115 if (EFI_ERROR (Status)) {\r
2116 goto Done;\r
2117 }\r
2118\r
2119 CopyMem ((UINT8 *) (Info + 1), &CreateDate, sizeof (EFI_USER_INFO_CREATE_DATE));\r
2120 NewInfo = NULL;\r
2121 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2122 if (EFI_ERROR (Status)) {\r
2123 goto Done;\r
2124 }\r
2125 \r
2126 //\r
2127 // Add user profile usage count record.\r
2128 //\r
2129 Info->InfoType = EFI_USER_INFO_USAGE_COUNT_RECORD;\r
2130 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2131 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_COUNT);\r
2132 UsageCount = 0;\r
2133 CopyMem ((UINT8 *) (Info + 1), &UsageCount, sizeof (EFI_USER_INFO_USAGE_COUNT));\r
2134 NewInfo = NULL;\r
2135 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2136 if (EFI_ERROR (Status)) {\r
2137 goto Done;\r
2138 }\r
2139 \r
2140 //\r
2141 // Add user access right.\r
2142 //\r
2143 Info->InfoType = EFI_USER_INFO_ACCESS_POLICY_RECORD;\r
2144 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2145 Access = (EFI_USER_INFO_ACCESS_CONTROL *) (Info + 1);\r
2146 Access->Type = EFI_USER_INFO_ACCESS_MANAGE;\r
2147 Access->Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL);\r
2148 Info->InfoSize = sizeof (EFI_USER_INFO) + Access->Size;\r
2149 NewInfo = NULL;\r
2150 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2151 if (EFI_ERROR (Status)) {\r
2152 goto Done;\r
2153 }\r
2154 \r
2155 //\r
2156 // Add user identity policy.\r
2157 //\r
2158 Info->InfoType = EFI_USER_INFO_IDENTITY_POLICY_RECORD;\r
2159 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PRIVATE | EFI_USER_INFO_EXCLUSIVE;\r
2160 Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (Info + 1);\r
2161 Policy->Type = EFI_USER_INFO_IDENTITY_TRUE;\r
2162 Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY); \r
2163 Info->InfoSize = sizeof (EFI_USER_INFO) + Policy->Length;\r
2164 NewInfo = NULL;\r
2165 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2166\r
2167Done:\r
2168 FreePool (Info);\r
2169 return Status;\r
2170}\r
2171\r
2172\r
2173/**\r
2174 Publish current user information into EFI System Configuration Table.\r
2175\r
2176 By UEFI spec, the User Identity Manager will publish the current user profile \r
2177 into the EFI System Configuration Table. Currently, only the user identifier and user\r
2178 name are published.\r
2179\r
2180 @retval EFI_SUCCESS Current user information is published successfully.\r
2181 @retval Others Fail to publish current user information\r
2182\r
2183**/\r
2184EFI_STATUS\r
2185PublishUserTable (\r
2186 VOID\r
2187 )\r
2188{\r
2189 EFI_STATUS Status;\r
2190 EFI_CONFIGURATION_TABLE *EfiConfigurationTable;\r
2191 EFI_USER_INFO_TABLE *UserInfoTable;\r
2192 EFI_USER_INFO *IdInfo;\r
2193 EFI_USER_INFO *NameInfo;\r
2194\r
2195 Status = EfiGetSystemConfigurationTable (\r
2196 &gEfiUserManagerProtocolGuid,\r
2197 (VOID **) &EfiConfigurationTable\r
2198 );\r
2199 if (!EFI_ERROR (Status)) {\r
2200 //\r
2201 // The table existed! \r
2202 //\r
2203 return EFI_SUCCESS;\r
2204 }\r
2205\r
2206 //\r
2207 // Get user ID information.\r
2208 //\r
2209 IdInfo = NULL;\r
2210 Status = FindUserInfoByType (mCurrentUser, &IdInfo, EFI_USER_INFO_IDENTIFIER_RECORD);\r
2211 if (EFI_ERROR (Status)) {\r
2212 return Status;\r
2213\r
2214 }\r
2215 //\r
2216 // Get user name information.\r
2217 //\r
2218 NameInfo = NULL;\r
2219 Status = FindUserInfoByType (mCurrentUser, &NameInfo, EFI_USER_INFO_NAME_RECORD);\r
2220 if (EFI_ERROR (Status)) {\r
2221 return Status;\r
2222 }\r
2223 \r
2224 //\r
2225 // Allocate a buffer for user information table.\r
2226 //\r
2227 UserInfoTable = (EFI_USER_INFO_TABLE *) AllocateRuntimePool (\r
2228 sizeof (EFI_USER_INFO_TABLE) + \r
2229 IdInfo->InfoSize + \r
2230 NameInfo->InfoSize\r
2231 );\r
2232 if (UserInfoTable == NULL) {\r
2233 Status = EFI_OUT_OF_RESOURCES;\r
2234 return Status;\r
2235 }\r
2236\r
2237 UserInfoTable->Size = sizeof (EFI_USER_INFO_TABLE); \r
2238 \r
2239 //\r
2240 // Append the user information to the user info table\r
2241 //\r
2242 CopyMem ((UINT8 *) UserInfoTable + UserInfoTable->Size, (UINT8 *) IdInfo, IdInfo->InfoSize);\r
2243 UserInfoTable->Size += IdInfo->InfoSize;\r
2244\r
2245 CopyMem ((UINT8 *) UserInfoTable + UserInfoTable->Size, (UINT8 *) NameInfo, NameInfo->InfoSize);\r
2246 UserInfoTable->Size += NameInfo->InfoSize;\r
2247\r
2248 Status = gBS->InstallConfigurationTable (&gEfiUserManagerProtocolGuid, (VOID *) UserInfoTable);\r
2249 return Status;\r
2250}\r
2251\r
2252\r
2253/**\r
2254 Get the user's identity type.\r
2255\r
2256 The identify manager only supports the identity policy in which the credential \r
2257 provider handles are connected by the operator 'AND' or 'OR'.\r
2258\r
2259\r
2260 @param[in] User Handle of a user profile.\r
2261 @param[out] PolicyType Point to the identity type.\r
2262\r
2263 @retval EFI_SUCCESS Get user's identity type successfully.\r
2264 @retval Others Fail to get user's identity type.\r
2265\r
2266**/\r
2267EFI_STATUS\r
2268GetIdentifyType (\r
2269 IN EFI_USER_PROFILE_HANDLE User,\r
2270 OUT UINT8 *PolicyType\r
2271 )\r
2272{\r
2273 EFI_STATUS Status;\r
2274 EFI_USER_INFO *IdentifyInfo;\r
2275 UINTN TotalLen;\r
2276 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
2277\r
2278 //\r
2279 // Get user identify policy information.\r
2280 //\r
2281 IdentifyInfo = NULL;\r
2282 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
2283 if (EFI_ERROR (Status)) {\r
2284 return Status;\r
2285 }\r
2286 ASSERT (IdentifyInfo != NULL);\r
2287 \r
2288 //\r
2289 // Search the user identify policy according to type.\r
2290 //\r
2291 TotalLen = 0;\r
2292 *PolicyType = EFI_USER_INFO_IDENTITY_FALSE;\r
2293 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
2294 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
2295 if (Identity->Type == EFI_USER_INFO_IDENTITY_AND) {\r
2296 *PolicyType = EFI_USER_INFO_IDENTITY_AND;\r
2297 break;\r
2298 }\r
2299\r
2300 if (Identity->Type == EFI_USER_INFO_IDENTITY_OR) {\r
2301 *PolicyType = EFI_USER_INFO_IDENTITY_OR;\r
2302 break;\r
2303 }\r
2304 TotalLen += Identity->Length;\r
2305 }\r
2306 return EFI_SUCCESS;\r
2307}\r
2308\r
2309\r
2310/**\r
2311 Identify the User by the specfied provider.\r
2312\r
2313 @param[in] User Handle of a user profile.\r
ae4cb94f 2314 @param[in] Provider Points to the identifier of credential provider.\r
0c18794e 2315\r
2316 @retval EFI_INVALID_PARAMETER Provider is NULL.\r
2317 @retval EFI_NOT_FOUND Fail to identify the specified user.\r
2318 @retval EFI_SUCCESS User is identified successfully.\r
2319\r
2320**/\r
2321EFI_STATUS\r
2322IdentifyByProviderId (\r
2323 IN EFI_USER_PROFILE_HANDLE User,\r
2324 IN EFI_GUID *Provider\r
2325 )\r
2326{\r
2327 EFI_STATUS Status;\r
2328 EFI_USER_INFO_IDENTIFIER UserId;\r
2329 UINTN Index;\r
2330 EFI_CREDENTIAL_LOGON_FLAGS AutoLogon;\r
2331 EFI_HII_HANDLE HiiHandle;\r
2332 EFI_GUID FormSetId;\r
2333 EFI_FORM_ID FormId;\r
2334 EFI_USER_CREDENTIAL_PROTOCOL *UserCredential;\r
0c18794e 2335\r
2336 if (Provider == NULL) {\r
2337 return EFI_INVALID_PARAMETER;\r
2338 }\r
2339 \r
2340 //\r
2341 // Check the user ID identified by the specified credential provider.\r
2342 //\r
2343 for (Index = 0; Index < mProviderDb->Count; Index++) {\r
2344 //\r
2345 // Check credential provider class.\r
2346 //\r
2347 UserCredential = mProviderDb->Provider[Index];\r
2348 if (CompareGuid (&UserCredential->Identifier, Provider)) {\r
2349 Status = UserCredential->Select (UserCredential, &AutoLogon);\r
2350 if (EFI_ERROR (Status)) {\r
2351 return Status;\r
2352 }\r
2353\r
2354 if ((AutoLogon & EFI_CREDENTIAL_LOGON_FLAG_AUTO) == 0) {\r
2355 //\r
2356 // Get credential provider form.\r
2357 //\r
2358 Status = UserCredential->Form (\r
2359 UserCredential, \r
2360 &HiiHandle, \r
2361 &FormSetId, \r
2362 &FormId\r
2363 );\r
2364 if (!EFI_ERROR (Status)) { \r
2365 //\r
2366 // Send form to get user input.\r
2367 //\r
2368 Status = mCallbackInfo->FormBrowser2->SendForm (\r
2369 mCallbackInfo->FormBrowser2,\r
2370 &HiiHandle,\r
2371 1,\r
2372 &FormSetId,\r
2373 FormId,\r
2374 NULL,\r
2375 NULL\r
2376 );\r
2377 if (EFI_ERROR (Status)) {\r
2378 return Status;\r
2379 } \r
2380 } \r
2381 }\r
2382\r
2383 Status = UserCredential->User (UserCredential, User, &UserId);\r
2384 if (EFI_ERROR (Status)) {\r
2385 return Status;\r
2386 }\r
2387\r
2388 Status = UserCredential->Deselect (UserCredential);\r
2389 if (EFI_ERROR (Status)) {\r
2390 return Status;\r
2391 }\r
0c18794e 2392 \r
0c18794e 2393 return EFI_SUCCESS;\r
2394 }\r
2395 }\r
2396\r
2397 return EFI_NOT_FOUND;\r
2398}\r
2399\r
2400\r
2401/**\r
2402 Update user information when user is logon on successfully.\r
2403\r
2404 @param[in] User Points to user profile.\r
2405\r
2406 @retval EFI_SUCCESS Update user information successfully.\r
2407 @retval Others Fail to update user information.\r
2408\r
2409**/\r
2410EFI_STATUS\r
2411UpdateUserInfo (\r
2412 IN USER_PROFILE_ENTRY *User\r
2413 )\r
2414{\r
2415 EFI_STATUS Status;\r
2416 EFI_USER_INFO *Info;\r
2417 EFI_USER_INFO *NewInfo;\r
2418 EFI_USER_INFO_CREATE_DATE Date;\r
2419 EFI_USER_INFO_USAGE_COUNT UsageCount;\r
2420 UINTN InfoLen;\r
2421\r
2422 //\r
2423 // Allocate a buffer to update user's date record and usage record.\r
2424 //\r
2425 InfoLen = MAX (sizeof (EFI_USER_INFO_CREATE_DATE), sizeof (EFI_USER_INFO_USAGE_COUNT));\r
2426 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + InfoLen);\r
2427 if (Info == NULL) {\r
2428 return EFI_OUT_OF_RESOURCES;\r
2429 }\r
2430 \r
2431 //\r
2432 // Check create date record.\r
2433 //\r
2434 NewInfo = NULL;\r
2435 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_CREATE_DATE_RECORD);\r
2436 if (Status == EFI_NOT_FOUND) {\r
2437 Info->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD;\r
2438 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2439 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE);\r
2440 Status = gRT->GetTime (&Date, NULL);\r
2441 if (EFI_ERROR (Status)) {\r
2442 FreePool (Info);\r
2443 return Status;\r
2444 }\r
2445\r
2446 CopyMem ((UINT8 *) (Info + 1), &Date, sizeof (EFI_USER_INFO_CREATE_DATE));\r
2447 NewInfo = NULL;\r
2448 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2449 if (EFI_ERROR (Status)) {\r
2450 FreePool (Info);\r
2451 return Status;\r
2452 }\r
2453 }\r
2454 \r
2455 //\r
2456 // Update usage date record.\r
2457 //\r
2458 NewInfo = NULL;\r
2459 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_USAGE_DATE_RECORD);\r
2460 if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {\r
2461 Info->InfoType = EFI_USER_INFO_USAGE_DATE_RECORD;\r
2462 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2463 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_DATE);\r
2464 Status = gRT->GetTime (&Date, NULL);\r
2465 if (EFI_ERROR (Status)) {\r
2466 FreePool (Info);\r
2467 return Status;\r
2468 }\r
2469\r
2470 CopyMem ((UINT8 *) (Info + 1), &Date, sizeof (EFI_USER_INFO_USAGE_DATE));\r
2471 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2472 if (EFI_ERROR (Status)) {\r
2473 FreePool (Info);\r
2474 return Status;\r
2475 }\r
2476 }\r
2477 \r
2478 //\r
2479 // Update usage count record.\r
2480 //\r
2481 UsageCount = 0;\r
2482 NewInfo = NULL;\r
2483 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_USAGE_COUNT_RECORD);\r
2484 //\r
2485 // Get usage count.\r
2486 //\r
2487 if (Status == EFI_SUCCESS) {\r
2488 CopyMem (&UsageCount, (UINT8 *) (NewInfo + 1), sizeof (EFI_USER_INFO_USAGE_COUNT));\r
2489 }\r
2490\r
2491 UsageCount++;\r
2492 if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {\r
2493 Info->InfoType = EFI_USER_INFO_USAGE_COUNT_RECORD;\r
2494 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2495 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_COUNT);\r
2496 CopyMem ((UINT8 *) (Info + 1), &UsageCount, sizeof (EFI_USER_INFO_USAGE_COUNT));\r
2497 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2498 if (EFI_ERROR (Status)) {\r
2499 FreePool (Info);\r
2500 return Status;\r
2501 }\r
2502 }\r
2503\r
2504 FreePool (Info);\r
2505 return EFI_SUCCESS;\r
2506}\r
2507\r
2508\r
2509/**\r
2510 Add a credenetial provider item in form.\r
2511\r
2512 @param[in] ProviderGuid Points to the identifir of credential provider.\r
2513 @param[in] OpCodeHandle Points to container for dynamic created opcodes.\r
2514\r
2515**/\r
2516VOID\r
2517AddProviderSelection (\r
2518 IN EFI_GUID *ProviderGuid,\r
2519 IN VOID *OpCodeHandle\r
2520 )\r
2521{\r
2522 EFI_HII_HANDLE HiiHandle;\r
2523 EFI_STRING_ID ProvID;\r
2524 CHAR16 *ProvStr;\r
2525 UINTN Index;\r
2526 EFI_USER_CREDENTIAL_PROTOCOL *UserCredential;\r
2527\r
2528 for (Index = 0; Index < mProviderDb->Count; Index++) {\r
2529 UserCredential = mProviderDb->Provider[Index];\r
2530 if (CompareGuid (&UserCredential->Identifier, ProviderGuid)) {\r
2531 //\r
2532 // Add credential provider selection.\r
2533 //\r
2534 UserCredential->Title (UserCredential, &HiiHandle, &ProvID);\r
2535 ProvStr = HiiGetString (HiiHandle, ProvID, NULL);\r
2536 if (ProvStr == NULL) {\r
2537 continue ;\r
2538 }\r
2539 ProvID = HiiSetString (mCallbackInfo->HiiHandle, 0, ProvStr, NULL);\r
2540 FreePool (ProvStr);\r
2541 HiiCreateActionOpCode (\r
2542 OpCodeHandle, // Container for dynamic created opcodes\r
2543 (EFI_QUESTION_ID)(LABEL_PROVIDER_NAME + Index), // Question ID\r
2544 ProvID, // Prompt text\r
2545 STRING_TOKEN (STR_NULL_STRING), // Help text\r
2546 EFI_IFR_FLAG_CALLBACK, // Question flag\r
2547 0 // Action String ID\r
2548 );\r
2549 break;\r
2550 }\r
2551 }\r
2552}\r
2553\r
2554\r
2555/**\r
2556 Add a username item in form.\r
2557\r
2558 @param[in] Index The index of the user in the user name list.\r
2559 @param[in] User Points to the user profile whose username is added. \r
2560 @param[in] OpCodeHandle Points to container for dynamic created opcodes.\r
2561\r
2562 @retval EFI_SUCCESS Add a username successfully.\r
2563 @retval Others Fail to add a username.\r
2564\r
2565**/\r
2566EFI_STATUS\r
2567AddUserSelection (\r
2568 IN UINT16 Index,\r
2569 IN USER_PROFILE_ENTRY *User,\r
2570 IN VOID *OpCodeHandle\r
2571 )\r
2572{\r
2573 EFI_STRING_ID UserName;\r
2574 EFI_STATUS Status;\r
2575 EFI_USER_INFO *UserInfo;\r
2576\r
2577 UserInfo = NULL;\r
2578 Status = FindUserInfoByType (User, &UserInfo, EFI_USER_INFO_NAME_RECORD);\r
2579 if (EFI_ERROR (Status)) {\r
2580 return Status;\r
2581 }\r
2582 \r
2583 //\r
2584 // Add user name selection.\r
2585 //\r
2586 UserName = HiiSetString (mCallbackInfo->HiiHandle, 0, (EFI_STRING) (UserInfo + 1), NULL);\r
2587 if (UserName == 0) {\r
2588 return EFI_OUT_OF_RESOURCES;\r
2589 }\r
2590\r
2591 HiiCreateGotoOpCode (\r
2592 OpCodeHandle, // Container for dynamic created opcodes\r
2593 FORMID_PROVIDER_FORM, // Target Form ID\r
2594 UserName, // Prompt text\r
2595 STRING_TOKEN (STR_NULL_STRING), // Help text\r
2596 EFI_IFR_FLAG_CALLBACK, // Question flag\r
2597 (UINT16) Index // Question ID\r
2598 );\r
2599\r
2600 return EFI_SUCCESS;\r
2601}\r
2602\r
2603\r
2604/**\r
2605 Identify the user whose identity policy does not contain the operator 'OR'.\r
2606 \r
2607 @param[in] User Points to the user profile.\r
2608\r
2609 @retval EFI_SUCCESS The specified user is identified successfully.\r
2610 @retval Others Fail to identify the user.\r
2611 \r
2612**/\r
2613EFI_STATUS\r
2614IdentifyAndTypeUser (\r
2615 IN USER_PROFILE_ENTRY *User\r
2616 )\r
2617{\r
2618 EFI_STATUS Status;\r
2619 EFI_USER_INFO *IdentifyInfo;\r
2620 BOOLEAN Success;\r
2621 UINTN TotalLen;\r
2622 UINTN ValueLen;\r
2623 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
2624\r
2625 //\r
2626 // Get user identify policy information.\r
2627 //\r
2628 IdentifyInfo = NULL;\r
2629 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
2630 if (EFI_ERROR (Status)) {\r
2631 return Status;\r
2632 }\r
2633 ASSERT (IdentifyInfo != NULL);\r
2634 \r
2635 //\r
2636 // Check each part of identification policy expression.\r
2637 //\r
2638 Success = FALSE;\r
2639 TotalLen = 0;\r
2640 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
2641 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
2642 ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
2643 switch (Identity->Type) {\r
2644\r
2645 case EFI_USER_INFO_IDENTITY_FALSE:\r
2646 //\r
2647 // Check False option.\r
2648 //\r
2649 Success = FALSE;\r
2650 break;\r
2651\r
2652 case EFI_USER_INFO_IDENTITY_TRUE:\r
2653 //\r
2654 // Check True option.\r
2655 //\r
2656 Success = TRUE;\r
2657 break;\r
2658\r
2659 case EFI_USER_INFO_IDENTITY_NOT:\r
2660 //\r
2661 // Check negative operation.\r
2662 //\r
2663 break;\r
2664\r
2665 case EFI_USER_INFO_IDENTITY_AND:\r
2666 //\r
2667 // Check and operation.\r
2668 //\r
2669 if (!Success) {\r
2670 return EFI_NOT_READY;\r
2671 }\r
2672\r
2673 Success = FALSE;\r
2674 break;\r
2675\r
2676 case EFI_USER_INFO_IDENTITY_OR:\r
2677 //\r
2678 // Check or operation.\r
2679 //\r
2680 if (Success) {\r
2681 return EFI_SUCCESS;\r
2682 }\r
2683 break;\r
2684\r
2685 case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:\r
2686 //\r
2687 // Check credential provider by type.\r
2688 //\r
2689 break;\r
2690\r
2691 case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:\r
2692 //\r
2693 // Check credential provider by ID.\r
2694 //\r
2695 if (ValueLen != sizeof (EFI_GUID)) {\r
2696 return EFI_INVALID_PARAMETER;\r
2697 }\r
2698\r
2699 Status = IdentifyByProviderId (User, (EFI_GUID *) (Identity + 1));\r
2700 if (EFI_ERROR (Status)) {\r
2701 return Status;\r
2702 }\r
2703\r
2704 Success = TRUE;\r
2705 break;\r
2706\r
2707 default:\r
2708 return EFI_INVALID_PARAMETER;\r
2709 break;\r
2710 }\r
2711\r
2712 TotalLen += Identity->Length;\r
2713 }\r
2714\r
2715 if (TotalLen != IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
2716 return EFI_INVALID_PARAMETER;\r
2717 }\r
2718\r
2719 if (!Success) {\r
2720 return EFI_NOT_READY;\r
2721 }\r
2722\r
2723 return EFI_SUCCESS;\r
2724}\r
2725\r
2726\r
2727/**\r
2728 Identify the user whose identity policy does not contain the operator 'AND'.\r
2729 \r
2730 @param[in] User Points to the user profile.\r
2731\r
2732 @retval EFI_SUCCESS The specified user is identified successfully.\r
2733 @retval Others Fail to identify the user.\r
2734 \r
2735**/\r
2736EFI_STATUS\r
2737IdentifyOrTypeUser (\r
2738 IN USER_PROFILE_ENTRY *User\r
2739 )\r
2740{\r
2741 EFI_STATUS Status;\r
2742 EFI_USER_INFO *IdentifyInfo;\r
2743 UINTN TotalLen;\r
2744 UINTN ValueLen;\r
2745 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
2746 VOID *StartOpCodeHandle;\r
2747 VOID *EndOpCodeHandle;\r
2748 EFI_IFR_GUID_LABEL *StartLabel;\r
2749 EFI_IFR_GUID_LABEL *EndLabel;\r
2750\r
2751 //\r
2752 // Get user identify policy information.\r
2753 //\r
2754 IdentifyInfo = NULL;\r
2755 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
2756 if (EFI_ERROR (Status)) {\r
2757 return Status;\r
2758 }\r
2759 ASSERT (IdentifyInfo != NULL);\r
2760 \r
2761 //\r
2762 // Initialize the container for dynamic opcodes.\r
2763 //\r
2764 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2765 ASSERT (StartOpCodeHandle != NULL);\r
2766\r
2767 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2768 ASSERT (EndOpCodeHandle != NULL);\r
2769\r
2770 //\r
2771 // Create Hii Extend Label OpCode.\r
2772 //\r
2773 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2774 StartOpCodeHandle,\r
2775 &gEfiIfrTianoGuid,\r
2776 NULL,\r
2777 sizeof (EFI_IFR_GUID_LABEL)\r
2778 );\r
2779 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2780 StartLabel->Number = LABEL_PROVIDER_NAME;\r
2781\r
2782 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2783 EndOpCodeHandle,\r
2784 &gEfiIfrTianoGuid,\r
2785 NULL,\r
2786 sizeof (EFI_IFR_GUID_LABEL)\r
2787 );\r
2788 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2789 EndLabel->Number = LABEL_END;\r
2790\r
2791 //\r
2792 // Add the providers that exists in the user's policy.\r
2793 //\r
2794 TotalLen = 0;\r
2795 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
2796 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
2797 ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
2798 if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
2799 AddProviderSelection ((EFI_GUID *) (Identity + 1), StartOpCodeHandle);\r
2800 }\r
2801\r
2802 TotalLen += Identity->Length;\r
2803 }\r
2804\r
2805 HiiUpdateForm (\r
2806 mCallbackInfo->HiiHandle, // HII handle\r
a0c56a82 2807 &gUserIdentifyManagerGuid,// Formset GUID\r
0c18794e 2808 FORMID_PROVIDER_FORM, // Form ID\r
2809 StartOpCodeHandle, // Label for where to insert opcodes\r
2810 EndOpCodeHandle // Replace data\r
2811 );\r
2812\r
2813 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
2814 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
2815\r
2816 return EFI_SUCCESS;\r
2817}\r
2818\r
2819\r
2820/**\r
2821 This function processes the results of changes in configuration.\r
2822\r
2823 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
2824 @param Action Specifies the type of action taken by the browser.\r
2825 @param QuestionId A unique value which is sent to the original\r
2826 exporting driver so that it can identify the type\r
2827 of data to expect.\r
2828 @param Type The type of value for the question.\r
2829 @param Value A pointer to the data being sent to the original\r
2830 exporting driver.\r
2831 @param ActionRequest On return, points to the action requested by the\r
2832 callback function.\r
2833\r
2834 @retval EFI_SUCCESS The callback successfully handled the action.\r
2835 @retval Others Fail to handle the action.\r
2836\r
2837**/\r
2838EFI_STATUS\r
2839EFIAPI\r
2840UserIdentifyManagerCallback (\r
2841 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
2842 IN EFI_BROWSER_ACTION Action,\r
2843 IN EFI_QUESTION_ID QuestionId,\r
2844 IN UINT8 Type,\r
2845 IN EFI_IFR_TYPE_VALUE *Value,\r
2846 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
2847 )\r
2848{\r
2849 EFI_STATUS Status;\r
2850 USER_PROFILE_ENTRY *User;\r
2851 UINT8 PolicyType;\r
2852 UINT16 Index;\r
2853 VOID *StartOpCodeHandle;\r
2854 VOID *EndOpCodeHandle;\r
2855 EFI_IFR_GUID_LABEL *StartLabel;\r
2856 EFI_IFR_GUID_LABEL *EndLabel;\r
2857\r
2858 Status = EFI_SUCCESS;\r
2859\r
2860 switch (Action) {\r
2861 case EFI_BROWSER_ACTION_FORM_OPEN:\r
2862 {\r
2863 //\r
2864 // Update user Form when user Form is opened.\r
2865 // This will be done only in FORM_OPEN CallBack of question with FORM_OPEN_QUESTION_ID from user Form.\r
2866 //\r
2867 if (QuestionId != FORM_OPEN_QUESTION_ID) {\r
2868 return EFI_SUCCESS;\r
2869 }\r
2870 \r
2871 //\r
2872 // Initialize the container for dynamic opcodes.\r
2873 //\r
2874 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2875 ASSERT (StartOpCodeHandle != NULL);\r
2876 \r
2877 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2878 ASSERT (EndOpCodeHandle != NULL);\r
2879 \r
2880 //\r
2881 // Create Hii Extend Label OpCode.\r
2882 //\r
2883 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2884 StartOpCodeHandle,\r
2885 &gEfiIfrTianoGuid,\r
2886 NULL,\r
2887 sizeof (EFI_IFR_GUID_LABEL)\r
2888 );\r
2889 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2890 StartLabel->Number = LABEL_USER_NAME;\r
2891 \r
2892 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2893 EndOpCodeHandle,\r
2894 &gEfiIfrTianoGuid,\r
2895 NULL,\r
2896 sizeof (EFI_IFR_GUID_LABEL)\r
2897 );\r
2898 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2899 EndLabel->Number = LABEL_END;\r
2900 \r
2901 //\r
2902 // Add all the user profile in the user profile database.\r
2903 //\r
2904 for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {\r
2905 User = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[Index];\r
2906 AddUserSelection ((UINT16)(LABEL_USER_NAME + Index), User, StartOpCodeHandle);\r
2907 }\r
2908 \r
2909 HiiUpdateForm (\r
2910 mCallbackInfo->HiiHandle, // HII handle\r
a0c56a82 2911 &gUserIdentifyManagerGuid,// Formset GUID\r
0c18794e 2912 FORMID_USER_FORM, // Form ID\r
2913 StartOpCodeHandle, // Label for where to insert opcodes\r
2914 EndOpCodeHandle // Replace data\r
2915 );\r
2916 \r
2917 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
2918 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
2919 \r
2920 return EFI_SUCCESS;\r
2921 }\r
2922 break;\r
2923\r
2924 case EFI_BROWSER_ACTION_FORM_CLOSE:\r
2925 Status = EFI_SUCCESS;\r
2926 break;\r
2927\r
2928 case EFI_BROWSER_ACTION_CHANGING:\r
2929 {\r
2930 if (QuestionId >= LABEL_PROVIDER_NAME) {\r
2931 //\r
2932 // QuestionId comes from the second Form (Select a Credential Provider if identity \r
2933 // policy is OR type). Identify the user by the selected provider.\r
2934 //\r
2935 Status = IdentifyByProviderId (mCurrentUser, &mProviderDb->Provider[QuestionId & 0xFFF]->Identifier);\r
2936 if (Status == EFI_SUCCESS) {\r
2937 mIdentified = TRUE;\r
2938 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
2939 }\r
2940 return EFI_SUCCESS;\r
2941 }\r
2942\r
2943 //\r
2944 // QuestionId comes from the first Form (Select a user to identify).\r
2945 //\r
2946 User = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[QuestionId & 0xFFF];\r
2947 Status = GetIdentifyType (User, &PolicyType);\r
2948 if (EFI_ERROR (Status)) {\r
2949 return Status;\r
2950 }\r
2951\r
2952 if (PolicyType == EFI_USER_INFO_IDENTITY_OR) {\r
2953 //\r
2954 // Identify the user by "OR" logical.\r
2955 //\r
2956 Status = IdentifyOrTypeUser (User);\r
2957 if (EFI_ERROR (Status)) {\r
2958 return Status;\r
2959 }\r
2960\r
2961 mCurrentUser = (EFI_USER_PROFILE_HANDLE) User;\r
2962 } else {\r
2963 //\r
2964 // Identify the user by "AND" logical.\r
2965 //\r
2966 Status = IdentifyAndTypeUser (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 mIdentified = TRUE;\r
2973 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
2974 }\r
2975 }\r
2976 break;\r
2977\r
2978 default:\r
2979 //\r
2980 // All other action return unsupported.\r
2981 //\r
2982 Status = EFI_UNSUPPORTED;\r
2983 break;\r
2984 }\r
2985\r
2986\r
2987 return Status;\r
2988}\r
2989\r
2990\r
2991/**\r
2992 This function construct user profile database from user data saved in the Flash.\r
2993 If no user is found in Flash, add one default user "administrator" in the user \r
2994 profile database.\r
2995\r
2996 @retval EFI_SUCCESS Init user profile database successfully.\r
2997 @retval Others Fail to init user profile database.\r
2998 \r
2999**/\r
3000EFI_STATUS\r
3001InitUserProfileDb (\r
3002 VOID\r
3003 )\r
3004{\r
3005 EFI_STATUS Status;\r
3006 UINT8 *VarData;\r
3007 UINTN VarSize;\r
3008 UINTN CurVarSize;\r
3009 CHAR16 VarName[10];\r
3010 UINTN Index;\r
3011 UINT32 VarAttr;\r
3012\r
3013 if (mUserProfileDb != NULL) {\r
3014 //\r
3015 // The user profiles had been already initialized.\r
3016 //\r
3017 return EFI_SUCCESS;\r
3018 }\r
3019\r
3020 //\r
3021 // Init user profile database structure.\r
3022 //\r
3023 if (!ExpandUsermUserProfileDb ()) {\r
3024 return EFI_OUT_OF_RESOURCES;\r
3025 }\r
3026\r
3027 CurVarSize = DEFAULT_PROFILE_SIZE;\r
3028 VarData = AllocateZeroPool (CurVarSize);\r
3029 if (VarData == NULL) {\r
3030 return EFI_OUT_OF_RESOURCES;\r
3031 }\r
3032 \r
3033 //\r
3034 // Get all user proifle entries.\r
3035 //\r
3036 Index = 0;\r
3037 while (TRUE) {\r
3038 //\r
3039 // Get variable name.\r
3040 //\r
3041 UnicodeSPrint (\r
3042 VarName, \r
3043 sizeof (VarName),\r
3044 L"User%04x", \r
3045 Index\r
3046 );\r
3047 Index++;\r
3048\r
3049 //\r
3050 // Get variable value.\r
3051 //\r
3052 VarSize = CurVarSize;\r
a0c56a82 3053 Status = gRT->GetVariable (VarName, &gUserIdentifyManagerGuid, &VarAttr, &VarSize, VarData);\r
0c18794e 3054 if (Status == EFI_BUFFER_TOO_SMALL) {\r
3055 FreePool (VarData);\r
3056 VarData = AllocatePool (VarSize);\r
3057 if (VarData == NULL) {\r
3058 Status = EFI_OUT_OF_RESOURCES;\r
3059 break;\r
3060 }\r
3061\r
3062 CurVarSize = VarSize;\r
a0c56a82 3063 Status = gRT->GetVariable (VarName, &gUserIdentifyManagerGuid, &VarAttr, &VarSize, VarData);\r
0c18794e 3064 }\r
3065\r
3066 if (EFI_ERROR (Status)) {\r
3067 if (Status == EFI_NOT_FOUND) {\r
3068 Status = EFI_SUCCESS;\r
3069 }\r
3070 break;\r
3071 }\r
3072 \r
3073 //\r
3074 // Check variable attributes.\r
3075 //\r
3076 if (VarAttr != (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)) {\r
a0c56a82 3077 Status = gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);\r
0c18794e 3078 continue;\r
3079 }\r
3080 \r
3081 //\r
3082 // Add user profile to the user profile database.\r
3083 //\r
3084 Status = AddUserProfile (NULL, VarSize, VarData, FALSE);\r
3085 if (EFI_ERROR (Status)) {\r
3086 if (Status == EFI_SECURITY_VIOLATION) {\r
3087 //\r
3088 // Delete invalid user profile\r
3089 //\r
a0c56a82 3090 gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);\r
0c18794e 3091 } else if (Status == EFI_OUT_OF_RESOURCES) {\r
3092 break;\r
3093 }\r
3094 } else {\r
3095 //\r
3096 // Delete and save the profile again if some invalid profiles are deleted.\r
3097 //\r
3098 if (mUserProfileDb->UserProfileNum < Index) {\r
a0c56a82 3099 gRT->SetVariable (VarName, &gUserIdentifyManagerGuid, VarAttr, 0, NULL);\r
0c18794e 3100 SaveNvUserProfile (mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum - 1], FALSE);\r
3101 }\r
3102 }\r
3103 }\r
3104\r
3105 if (VarData != NULL) {\r
3106 FreePool (VarData);\r
3107 }\r
3108\r
3109 if (EFI_ERROR (Status)) {\r
3110 return Status;\r
3111 }\r
3112 \r
3113 //\r
3114 // Check whether the user profile database is empty.\r
3115 //\r
3116 if (mUserProfileDb->UserProfileNum == 0) {\r
3117 Status = AddDefaultUserProfile ();\r
3118 }\r
3119\r
3120 return Status;\r
3121}\r
3122\r
3123\r
3124/**\r
3125 This function collects all the credential providers and saves to mProviderDb.\r
3126\r
3127 @retval EFI_SUCCESS Collect credential providers successfully.\r
3128 @retval Others Fail to collect credential providers.\r
3129\r
3130**/\r
3131EFI_STATUS\r
3132InitProviderInfo (\r
3133 VOID\r
3134 )\r
3135{\r
3136 EFI_STATUS Status;\r
3137 UINTN HandleCount;\r
3138 EFI_HANDLE *HandleBuf;\r
3139 UINTN Index; \r
3140\r
3141 if (mProviderDb != NULL) {\r
3142 //\r
3143 // The credential providers had been collected before.\r
3144 //\r
3145 return EFI_SUCCESS;\r
3146 }\r
3147\r
3148 //\r
3149 // Try to find all the user credential provider driver.\r
3150 //\r
3151 HandleCount = 0;\r
3152 HandleBuf = NULL;\r
3153 Status = gBS->LocateHandleBuffer (\r
3154 ByProtocol,\r
3155 &gEfiUserCredentialProtocolGuid,\r
3156 NULL,\r
3157 &HandleCount,\r
3158 &HandleBuf\r
3159 );\r
3160 if (EFI_ERROR (Status)) {\r
3161 return Status;\r
3162 }\r
3163\r
3164 //\r
3165 // Get provider infomation.\r
3166 //\r
3167 mProviderDb = AllocateZeroPool (\r
3168 sizeof (CREDENTIAL_PROVIDER_INFO) - \r
3169 sizeof (EFI_USER_CREDENTIAL_PROTOCOL *) + \r
3170 HandleCount * sizeof (EFI_USER_CREDENTIAL_PROTOCOL *)\r
3171 );\r
3172 if (mProviderDb == NULL) {\r
3173 FreePool (HandleBuf);\r
3174 return EFI_OUT_OF_RESOURCES;\r
3175 }\r
3176\r
3177 mProviderDb->Count = HandleCount;\r
3178 for (Index = 0; Index < HandleCount; Index++) {\r
3179 Status = gBS->HandleProtocol (\r
3180 HandleBuf[Index],\r
3181 &gEfiUserCredentialProtocolGuid,\r
3182 (VOID **) &mProviderDb->Provider[Index]\r
3183 );\r
3184 if (EFI_ERROR (Status)) {\r
3185 FreePool (HandleBuf);\r
3186 FreePool (mProviderDb);\r
3187 mProviderDb = NULL;\r
3188 return Status;\r
3189 }\r
3190 }\r
3191\r
3192 FreePool (HandleBuf);\r
3193 return EFI_SUCCESS;\r
3194}\r
3195\r
3196\r
3197/**\r
3198 This function allows a caller to extract the current configuration for one\r
3199 or more named elements from the target driver.\r
3200\r
3201\r
3202 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
3203 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
3204 @param Progress On return, points to a character in the Request string.\r
3205 Points to the string's null terminator if request was successful.\r
3206 Points to the most recent '&' before the first failing name/value\r
3207 pair (or the beginning of the string if the failure is in the\r
3208 first name/value pair) if the request was not successful.\r
3209 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
3210 has all values filled in for the names in the Request string.\r
3211 String to be allocated by the called function.\r
3212\r
3213 @retval EFI_SUCCESS The Results is filled with the requested values.\r
3214 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
3215 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
3216 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
3217\r
3218**/\r
3219EFI_STATUS\r
3220EFIAPI\r
3221FakeExtractConfig (\r
3222 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
3223 IN CONST EFI_STRING Request,\r
3224 OUT EFI_STRING *Progress,\r
3225 OUT EFI_STRING *Results\r
3226 )\r
3227{\r
3228 if (Progress == NULL || Results == NULL) {\r
3229 return EFI_INVALID_PARAMETER;\r
3230 }\r
3231 *Progress = Request;\r
3232 return EFI_NOT_FOUND;\r
3233}\r
3234\r
3235/**\r
3236 This function processes the results of changes in configuration.\r
3237\r
3238\r
3239 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
3240 @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
3241 @param Progress A pointer to a string filled in with the offset of the most\r
3242 recent '&' before the first failing name/value pair (or the\r
3243 beginning of the string if the failure is in the first\r
3244 name/value pair) or the terminating NULL if all was successful.\r
3245\r
3246 @retval EFI_SUCCESS The Results is processed successfully.\r
3247 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
3248 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
3249\r
3250**/\r
3251EFI_STATUS\r
3252EFIAPI\r
3253FakeRouteConfig (\r
3254 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
3255 IN CONST EFI_STRING Configuration,\r
3256 OUT EFI_STRING *Progress\r
3257 )\r
3258{\r
3259 if (Configuration == NULL || Progress == NULL) {\r
3260 return EFI_INVALID_PARAMETER;\r
3261 }\r
3262\r
3263 return EFI_NOT_FOUND;\r
3264}\r
3265\r
3266\r
3267/**\r
3268 This function initialize the data mainly used in form browser.\r
3269\r
3270 @retval EFI_SUCCESS Initialize form data successfully.\r
3271 @retval Others Fail to Initialize form data.\r
3272\r
3273**/\r
3274EFI_STATUS\r
3275InitFormBrowser (\r
3276 VOID\r
3277 )\r
3278{\r
3279 EFI_STATUS Status;\r
3280 USER_MANAGER_CALLBACK_INFO *CallbackInfo;\r
3281 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
3282 EFI_HII_STRING_PROTOCOL *HiiString;\r
3283 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
3284\r
3285 //\r
3286 // Initialize driver private data.\r
3287 //\r
3288 CallbackInfo = AllocateZeroPool (sizeof (USER_MANAGER_CALLBACK_INFO));\r
3289 if (CallbackInfo == NULL) {\r
3290 return EFI_OUT_OF_RESOURCES;\r
3291 }\r
3292\r
3293 CallbackInfo->Signature = USER_MANAGER_SIGNATURE;\r
3294 CallbackInfo->ConfigAccess.ExtractConfig = FakeExtractConfig;\r
3295 CallbackInfo->ConfigAccess.RouteConfig = FakeRouteConfig;\r
3296 CallbackInfo->ConfigAccess.Callback = UserIdentifyManagerCallback;\r
3297\r
3298 //\r
3299 // Locate Hii Database protocol.\r
3300 //\r
3301 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);\r
3302 if (EFI_ERROR (Status)) {\r
3303 return Status;\r
3304 }\r
3305 CallbackInfo->HiiDatabase = HiiDatabase;\r
3306\r
3307 //\r
3308 // Locate HiiString protocol.\r
3309 //\r
3310 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
3311 if (EFI_ERROR (Status)) {\r
3312 return Status;\r
3313 }\r
3314 CallbackInfo->HiiString = HiiString;\r
3315\r
3316 //\r
3317 // Locate Formbrowser2 protocol.\r
3318 //\r
3319 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
3320 if (EFI_ERROR (Status)) {\r
3321 return Status;\r
3322 }\r
3323\r
3324 CallbackInfo->FormBrowser2 = FormBrowser2;\r
3325 CallbackInfo->DriverHandle = NULL;\r
3326 \r
3327 //\r
3328 // Install Device Path Protocol and Config Access protocol to driver handle.\r
3329 //\r
3330 Status = gBS->InstallMultipleProtocolInterfaces (\r
3331 &CallbackInfo->DriverHandle,\r
3332 &gEfiDevicePathProtocolGuid,\r
3333 &mHiiVendorDevicePath,\r
3334 &gEfiHiiConfigAccessProtocolGuid,\r
3335 &CallbackInfo->ConfigAccess,\r
3336 NULL\r
3337 );\r
3338 ASSERT_EFI_ERROR (Status);\r
3339\r
3340 //\r
3341 // Publish HII data.\r
3342 //\r
3343 CallbackInfo->HiiHandle = HiiAddPackages (\r
a0c56a82 3344 &gUserIdentifyManagerGuid,\r
0c18794e 3345 CallbackInfo->DriverHandle,\r
3346 UserIdentifyManagerStrings,\r
3347 UserIdentifyManagerVfrBin,\r
3348 NULL\r
3349 );\r
3350 if (CallbackInfo->HiiHandle == NULL) {\r
3351 return EFI_OUT_OF_RESOURCES;\r
3352 }\r
3353\r
3354 mCallbackInfo = CallbackInfo;\r
3355\r
3356 return EFI_SUCCESS;\r
3357}\r
3358\r
3359\r
3360/**\r
3361 Identify the user whose identification policy supports auto logon.\r
3362\r
3363 @param[in] ProviderIndex The provider index in the provider list.\r
3364 @param[out] User Points to user user profile if a user is identified successfully.\r
3365\r
3366 @retval EFI_SUCCESS Identify a user with the specified provider successfully.\r
3367 @retval Others Fail to identify a user.\r
3368\r
3369**/\r
3370EFI_STATUS\r
3371IdentifyAutoLogonUser (\r
3372 IN UINTN ProviderIndex,\r
3373 OUT USER_PROFILE_ENTRY **User\r
3374 )\r
3375{\r
3376 EFI_STATUS Status;\r
3377 EFI_USER_INFO *Info;\r
3378 UINT8 PolicyType;\r
3379\r
3380 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER));\r
3381 if (Info == NULL) {\r
3382 return EFI_OUT_OF_RESOURCES;\r
3383 }\r
3384\r
3385 Info->InfoType = EFI_USER_INFO_IDENTIFIER_RECORD;\r
3386 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER);\r
3387\r
3388 //\r
3389 // Identify the specified credential provider's auto logon user.\r
3390 //\r
3391 Status = mProviderDb->Provider[ProviderIndex]->User (\r
3392 mProviderDb->Provider[ProviderIndex],\r
3393 NULL,\r
3394 (EFI_USER_INFO_IDENTIFIER *) (Info + 1)\r
3395 );\r
3396 if (EFI_ERROR (Status)) {\r
3397 FreePool (Info);\r
3398 return Status;\r
3399 }\r
3400 \r
3401 //\r
3402 // Find user with the specified user ID.\r
3403 //\r
3404 *User = NULL;\r
3405 Status = FindUserProfileByInfo (User, NULL, Info, Info->InfoSize);\r
3406 FreePool (Info);\r
3407 if (EFI_ERROR (Status)) {\r
3408 return Status;\r
3409 }\r
3410\r
3411 Status = GetIdentifyType ((EFI_USER_PROFILE_HANDLE) * User, &PolicyType);\r
3412 if (PolicyType == EFI_USER_INFO_IDENTITY_AND) {\r
3413 //\r
3414 // The identified user need also identified by other credential provider.\r
3415 // This can handle through select user.\r
3416 //\r
3417 return EFI_NOT_READY;\r
3418 }\r
3419 \r
3420 return Status;\r
3421}\r
3422\r
3423\r
3424/**\r
3425 Check whether the given console is ready.\r
3426\r
3427 @param[in] ProtocolGuid Points to the protocol guid of sonsole .\r
3428 \r
3429 @retval TRUE The given console is ready.\r
3430 @retval FALSE The given console is not ready.\r
3431 \r
3432**/\r
3433BOOLEAN\r
3434CheckConsole (\r
3435 EFI_GUID *ProtocolGuid \r
3436 )\r
3437{\r
3438 EFI_STATUS Status;\r
3439 UINTN HandleCount;\r
3440 EFI_HANDLE *HandleBuf;\r
3441 UINTN Index; \r
3442 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
3443 \r
3444 //\r
3445 // Try to find all the handle driver.\r
3446 //\r
3447 HandleCount = 0;\r
3448 HandleBuf = NULL;\r
3449 Status = gBS->LocateHandleBuffer (\r
3450 ByProtocol,\r
3451 ProtocolGuid,\r
3452 NULL,\r
3453 &HandleCount,\r
3454 &HandleBuf\r
3455 );\r
3456 if (EFI_ERROR (Status)) {\r
3457 return FALSE;\r
3458 }\r
3459\r
3460 for (Index = 0; Index < HandleCount; Index++) {\r
3461 DevicePath = DevicePathFromHandle (HandleBuf[Index]);\r
3462 if (DevicePath != NULL) {\r
3463 FreePool (HandleBuf);\r
3464 return TRUE;\r
3465 }\r
3466 }\r
3467 FreePool (HandleBuf); \r
3468 return FALSE;\r
3469}\r
3470\r
3471\r
3472/**\r
3473 Check whether the console is ready.\r
3474\r
3475 @retval TRUE The console is ready.\r
3476 @retval FALSE The console is not ready.\r
3477 \r
3478**/\r
3479BOOLEAN\r
3480IsConsoleReady (\r
3481 VOID\r
3482 )\r
3483{\r
3484 if (!CheckConsole (&gEfiSimpleTextOutProtocolGuid)) {\r
3485 return FALSE;\r
3486 }\r
3487\r
3488 if (!CheckConsole (&gEfiSimpleTextInProtocolGuid)) {\r
3489 if (!CheckConsole (&gEfiSimpleTextInputExProtocolGuid)) {\r
3490 return FALSE;\r
3491 }\r
3492 }\r
3493 \r
3494 return TRUE;\r
3495}\r
3496\r
3497\r
3498/**\r
3499 Identify a user to logon.\r
3500\r
3501 @param[out] User Points to user user profile if a user is identified successfully.\r
3502\r
3503 @retval EFI_SUCCESS Identify a user successfully.\r
3504\r
3505**/\r
3506EFI_STATUS\r
3507IdentifyUser (\r
3508 OUT USER_PROFILE_ENTRY **User\r
3509 )\r
3510{\r
3511 EFI_STATUS Status;\r
3512 UINTN Index;\r
3513 EFI_CREDENTIAL_LOGON_FLAGS AutoLogon;\r
3514 EFI_USER_INFO *IdentifyInfo;\r
3515 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
3516 EFI_USER_CREDENTIAL_PROTOCOL *UserCredential;\r
3517 USER_PROFILE_ENTRY *UserEntry;\r
3518\r
3519 //\r
3520 // Initialize credential providers.\r
3521 //\r
3522 InitProviderInfo ();\r
3523\r
3524 //\r
3525 // Initialize user profile database.\r
3526 //\r
3527 InitUserProfileDb ();\r
3528\r
3529 //\r
3530 // If only one user in system, and its identify policy is TRUE, then auto logon.\r
3531 //\r
3532 if (mUserProfileDb->UserProfileNum == 1) {\r
3533 UserEntry = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[0];\r
3534 IdentifyInfo = NULL;\r
3535 Status = FindUserInfoByType (UserEntry, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
3536 if (EFI_ERROR (Status)) {\r
3537 return Status;\r
3538 }\r
3539 ASSERT (IdentifyInfo != NULL);\r
3540\r
3541 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1));\r
3542 if (Identity->Type == EFI_USER_INFO_IDENTITY_TRUE) {\r
3543 mCurrentUser = (EFI_USER_PROFILE_HANDLE) UserEntry;\r
3544 UpdateUserInfo (UserEntry);\r
3545 *User = UserEntry;\r
3546 return EFI_SUCCESS;\r
3547 }\r
3548 }\r
3549 \r
3550 //\r
3551 // Find and login the default & AutoLogon user.\r
3552 //\r
3553 for (Index = 0; Index < mProviderDb->Count; Index++) {\r
3554 UserCredential = mProviderDb->Provider[Index];\r
3555 Status = UserCredential->Default (UserCredential, &AutoLogon);\r
3556 if (EFI_ERROR (Status)) {\r
3557 continue;\r
3558 }\r
3559\r
3560 if ((AutoLogon & (EFI_CREDENTIAL_LOGON_FLAG_DEFAULT | EFI_CREDENTIAL_LOGON_FLAG_AUTO)) != 0) {\r
3561 Status = IdentifyAutoLogonUser (Index, &UserEntry);\r
3562 if (Status == EFI_SUCCESS) {\r
3563 mCurrentUser = (EFI_USER_PROFILE_HANDLE) UserEntry;\r
3564 UpdateUserInfo (UserEntry);\r
3565 *User = UserEntry;\r
3566 return EFI_SUCCESS;\r
3567 }\r
3568 }\r
3569 }\r
3570 \r
3571 if (!IsConsoleReady ()) {\r
3572 //\r
3573 // The console is still not ready for user selection.\r
3574 //\r
3575 return EFI_ACCESS_DENIED;\r
3576 }\r
3577\r
3578 //\r
3579 // Select a user and identify it.\r
3580 //\r
3581 mCallbackInfo->FormBrowser2->SendForm (\r
3582 mCallbackInfo->FormBrowser2,\r
3583 &mCallbackInfo->HiiHandle,\r
3584 1,\r
a0c56a82 3585 &gUserIdentifyManagerGuid,\r
0c18794e 3586 0,\r
3587 NULL,\r
3588 NULL\r
3589 );\r
3590 \r
3591 if (mIdentified) {\r
3592 *User = (USER_PROFILE_ENTRY *) mCurrentUser;\r
3593 UpdateUserInfo (*User);\r
3594 return EFI_SUCCESS;\r
3595 }\r
3596 \r
3597 return EFI_ACCESS_DENIED;\r
3598}\r
3599\r
3600\r
3601/**\r
3602 An empty function to pass error checking of CreateEventEx ().\r
3603 \r
3604 @param Event Event whose notification function is being invoked.\r
3605 @param Context Pointer to the notification function's context,\r
3606 which is implementation-dependent.\r
3607\r
3608**/\r
3609VOID\r
3610EFIAPI\r
3611InternalEmptyFuntion (\r
3612 IN EFI_EVENT Event,\r
3613 IN VOID *Context\r
3614 )\r
3615{\r
3616}\r
3617\r
3618\r
3619/**\r
3620 Create, Signal, and Close the User Profile Changed event.\r
3621\r
3622**/\r
3623VOID\r
3624SignalEventUserProfileChanged (\r
3625 VOID\r
3626 )\r
3627{\r
3628 EFI_STATUS Status;\r
3629 EFI_EVENT Event;\r
3630\r
3631 Status = gBS->CreateEventEx (\r
3632 EVT_NOTIFY_SIGNAL,\r
3633 TPL_CALLBACK,\r
3634 InternalEmptyFuntion,\r
3635 NULL,\r
3636 &gEfiEventUserProfileChangedGuid,\r
3637 &Event\r
3638 );\r
3639 ASSERT_EFI_ERROR (Status);\r
3640 gBS->SignalEvent (Event);\r
3641 gBS->CloseEvent (Event);\r
3642}\r
3643\r
3644\r
3645/**\r
3646 Create a new user profile.\r
3647\r
3648 This function creates a new user profile with only a new user identifier attached and returns \r
3649 its handle. The user profile is non-volatile, but the handle User can change across reboots.\r
3650\r
3651 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3652 @param[out] User On return, points to the new user profile handle. \r
3653 The user profile handle is unique only during this boot.\r
3654 \r
3655 @retval EFI_SUCCESS User profile was successfully created.\r
3656 @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to create a \r
3657 user profile.\r
3658 @retval EFI_UNSUPPORTED Creation of new user profiles is not supported.\r
3659 @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
3660 \r
3661**/\r
3662EFI_STATUS\r
3663EFIAPI\r
3664UserProfileCreate (\r
3665 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3666 OUT EFI_USER_PROFILE_HANDLE *User\r
3667 )\r
3668{\r
3669 EFI_STATUS Status;\r
3670\r
3671 if ((This == NULL) || (User == NULL)) {\r
3672 return EFI_INVALID_PARAMETER;\r
3673 }\r
3674\r
3675 //\r
3676 // Check the right of the current user.\r
3677 //\r
3678 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
3679 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS)) {\r
3680 return EFI_ACCESS_DENIED;\r
3681 }\r
3682 }\r
3683 \r
3684 //\r
3685 // Create new user profile\r
3686 //\r
3687 Status = CreateUserProfile ((USER_PROFILE_ENTRY **) User);\r
3688 if (EFI_ERROR (Status)) {\r
3689 return EFI_ACCESS_DENIED;\r
3690 }\r
3691 return EFI_SUCCESS;\r
3692}\r
3693\r
3694\r
3695/**\r
3696 Delete an existing user profile.\r
3697\r
3698 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3699 @param[in] User User profile handle. \r
3700\r
3701 @retval EFI_SUCCESS User profile was successfully deleted.\r
3702 @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to delete a user\r
3703 profile or there is only one user profile.\r
3704 @retval EFI_UNSUPPORTED Deletion of new user profiles is not supported.\r
3705 @retval EFI_INVALID_PARAMETER User does not refer to a valid user profile.\r
3706 \r
3707**/\r
3708EFI_STATUS\r
3709EFIAPI\r
3710UserProfileDelete (\r
3711 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3712 IN EFI_USER_PROFILE_HANDLE User\r
3713 )\r
3714{\r
3715 EFI_STATUS Status;\r
3716\r
3717 if (This == NULL) {\r
3718 return EFI_INVALID_PARAMETER;\r
3719 }\r
3720 \r
3721 //\r
3722 // Check the right of the current user.\r
3723 //\r
3724 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
3725 return EFI_ACCESS_DENIED;\r
3726 }\r
3727 \r
3728 //\r
3729 // Delete user profile.\r
3730 //\r
3731 Status = DelUserProfile (User);\r
3732 if (EFI_ERROR (Status)) {\r
3733 if (Status != EFI_INVALID_PARAMETER) {\r
3734 return EFI_ACCESS_DENIED;\r
3735 }\r
3736 return EFI_INVALID_PARAMETER;\r
3737 }\r
3738\r
3739 return EFI_SUCCESS;\r
3740}\r
3741\r
3742\r
3743/**\r
3744 Enumerate all of the enrolled users on the platform.\r
3745\r
3746 This function returns the next enrolled user profile. To retrieve the first user profile handle, \r
3747 point User at a NULL. Each subsequent call will retrieve another user profile handle until there \r
3748 are no more, at which point User will point to NULL. \r
3749\r
3750 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3751 @param[in, out] User On entry, points to the previous user profile handle or NULL to \r
3752 start enumeration. On exit, points to the next user profile handle\r
3753 or NULL if there are no more user profiles.\r
3754\r
3755 @retval EFI_SUCCESS Next enrolled user profile successfully returned. \r
3756 @retval EFI_ACCESS_DENIED Next enrolled user profile was not successfully returned.\r
3757 @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
3758**/\r
3759EFI_STATUS\r
3760EFIAPI\r
3761UserProfileGetNext (\r
3762 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3763 IN OUT EFI_USER_PROFILE_HANDLE *User\r
3764 )\r
3765{\r
3766 EFI_STATUS Status;\r
3767\r
3768 if ((This == NULL) || (User == NULL)) {\r
3769 return EFI_INVALID_PARAMETER;\r
3770 }\r
3771 \r
3772 Status = FindUserProfile ((USER_PROFILE_ENTRY **) User, TRUE, NULL);\r
3773 if (EFI_ERROR (Status)) {\r
3774 return EFI_ACCESS_DENIED;\r
3775 }\r
3776 return EFI_SUCCESS;\r
3777}\r
3778\r
3779\r
3780/**\r
3781 Return the current user profile handle.\r
3782\r
3783 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3784 @param[out] CurrentUser On return, points to the current user profile handle.\r
3785\r
3786 @retval EFI_SUCCESS Current user profile handle returned successfully. \r
3787 @retval EFI_INVALID_PARAMETER The CurrentUser parameter is NULL.\r
3788 \r
3789**/\r
3790EFI_STATUS\r
3791EFIAPI\r
3792UserProfileCurrent (\r
3793 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3794 OUT EFI_USER_PROFILE_HANDLE *CurrentUser\r
3795 )\r
3796{ \r
3797 //\r
3798 // Get current user profile.\r
3799 //\r
3800 if ((This == NULL) || (CurrentUser == NULL)) {\r
3801 return EFI_INVALID_PARAMETER;\r
3802 }\r
3803\r
3804 *CurrentUser = mCurrentUser;\r
3805 return EFI_SUCCESS;\r
3806}\r
3807\r
3808\r
3809/**\r
3810 Identify a user.\r
3811\r
3812 Identify the user and, if authenticated, returns the user handle and changes the current\r
3813 user profile. All user information marked as private in a previously selected profile\r
3814 is no longer available for inspection. \r
3815 Whenever the current user profile is changed then the an event with the GUID \r
3816 EFI_EVENT_GROUP_USER_PROFILE_CHANGED is signaled.\r
3817\r
3818 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3819 @param[out] User On return, points to the user profile handle for the current\r
3820 user profile.\r
3821\r
3822 @retval EFI_SUCCESS User was successfully identified.\r
3823 @retval EFI_ACCESS_DENIED User was not successfully identified.\r
3824 @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
3825 \r
3826**/\r
3827EFI_STATUS\r
3828EFIAPI\r
3829UserProfileIdentify (\r
3830 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3831 OUT EFI_USER_PROFILE_HANDLE *User\r
3832 )\r
3833{\r
3834 EFI_STATUS Status;\r
3835\r
3836 if ((This == NULL) || (User == NULL)) {\r
3837 return EFI_INVALID_PARAMETER;\r
3838 }\r
3839\r
3840 if (mCurrentUser != NULL) {\r
3841 *User = mCurrentUser;\r
3842 return EFI_SUCCESS;\r
3843 }\r
3844 \r
3845 //\r
3846 // Identify user\r
3847 //\r
3848 Status = IdentifyUser ((USER_PROFILE_ENTRY **) User);\r
3849 if (EFI_ERROR (Status)) {\r
3850 return EFI_ACCESS_DENIED;\r
3851 }\r
3852 \r
3853 //\r
3854 // Publish the user info into the EFI system configuration table.\r
3855 //\r
3856 PublishUserTable ();\r
3857\r
3858 //\r
3859 // Signal User Profile Changed event.\r
3860 //\r
3861 SignalEventUserProfileChanged ();\r
3862 return EFI_SUCCESS;\r
3863}\r
3864\r
3865/**\r
3866 Find a user using a user information record.\r
3867\r
3868 This function searches all user profiles for the specified user information record.\r
3869 The search starts with the user information record handle following UserInfo and \r
3870 continues until either the information is found or there are no more user profiles.\r
3871 A match occurs when the Info.InfoType field matches the user information record\r
3872 type and the user information record data matches the portion of Info.\r
3873\r
3874 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3875 @param[in, out] User On entry, points to the previously returned user profile \r
3876 handle, or NULL to start searching with the first user profile.\r
3877 On return, points to the user profile handle, or NULL if not\r
3878 found.\r
3879 @param[in, out] UserInfo On entry, points to the previously returned user information\r
3880 handle, or NULL to start searching with the first. On return, \r
3881 points to the user information handle of the user information\r
3882 record, or NULL if not found. Can be NULL, in which case only \r
3883 one user information record per user can be returned. \r
3884 @param[in] Info Points to the buffer containing the user information to be \r
3885 compared to the user information record. If the user information \r
3886 record data is empty, then only the user information record type \r
3887 is compared. If InfoSize is 0, then the user information record \r
3888 must be empty.\r
3889\r
3890 @param[in] InfoSize The size of Info, in bytes. \r
3891\r
3892 @retval EFI_SUCCESS User information was found. User points to the user profile\r
3893 handle, and UserInfo points to the user information handle.\r
3894 @retval EFI_NOT_FOUND User information was not found. User points to NULL, and \r
3895 UserInfo points to NULL.\r
3896 @retval EFI_INVALID_PARAMETER User is NULL. Or Info is NULL. \r
3897 \r
3898**/\r
3899EFI_STATUS\r
3900EFIAPI\r
3901UserProfileFind (\r
3902 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3903 IN OUT EFI_USER_PROFILE_HANDLE *User,\r
3904 IN OUT EFI_USER_INFO_HANDLE *UserInfo OPTIONAL,\r
3905 IN CONST EFI_USER_INFO *Info,\r
3906 IN UINTN InfoSize\r
3907 )\r
3908{\r
3909 EFI_STATUS Status;\r
3910 UINTN Size;\r
3911\r
3912 if ((This == NULL) || (User == NULL) || (Info == NULL)) {\r
3913 return EFI_INVALID_PARAMETER;\r
3914 }\r
3915\r
3916 if (InfoSize == 0) {\r
3917 //\r
3918 // If InfoSize is 0, then the user information record must be empty.\r
3919 //\r
3920 if (Info->InfoSize != sizeof (EFI_USER_INFO)) {\r
3921 return EFI_INVALID_PARAMETER;\r
3922 }\r
3923 } else {\r
3924 if (InfoSize != Info->InfoSize) {\r
3925 return EFI_INVALID_PARAMETER;\r
3926 }\r
3927 }\r
3928 Size = Info->InfoSize; \r
3929 \r
3930 //\r
3931 // Find user profile accdoring to user information.\r
3932 //\r
3933 Status = FindUserProfileByInfo (\r
3934 (USER_PROFILE_ENTRY **) User,\r
3935 (EFI_USER_INFO **) UserInfo,\r
3936 (EFI_USER_INFO *) Info,\r
3937 Size\r
3938 );\r
3939 if (EFI_ERROR (Status)) {\r
3940 *User = NULL;\r
3941 if (UserInfo != NULL) {\r
3942 *UserInfo = NULL;\r
3943 }\r
3944 return EFI_NOT_FOUND;\r
3945 }\r
3946 \r
3947 return EFI_SUCCESS;\r
3948}\r
3949\r
3950\r
3951/**\r
3952 Return information attached to the user.\r
3953\r
3954 This function returns user information. The format of the information is described in User \r
3955 Information. The function may return EFI_ACCESS_DENIED if the information is marked private \r
3956 and the handle specified by User is not the current user profile. The function may return \r
3957 EFI_ACCESS_DENIED if the information is marked protected and the information is associated \r
3958 with a credential provider for which the user has not been authenticated.\r
3959\r
3960 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3961 @param[in] User Handle of the user whose profile will be retrieved. \r
3962 @param[in] UserInfo Handle of the user information data record. \r
3963 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes. On exit, \r
3964 holds the user information. If the buffer is too small to hold the \r
3965 information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is \r
3966 updated to contain the number of bytes actually required. \r
3967 @param[in, out] InfoSize On entry, points to the size of Info. On return, points to the size \r
3968 of the user information. \r
3969\r
3970 @retval EFI_SUCCESS Information returned successfully.\r
3971 @retval EFI_ACCESS_DENIED The information about the specified user cannot be accessed by the \r
3972 current user.\r
3973 @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the \r
3974 returned data. The actual size required is returned in *InfoSize.\r
3975 @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not refer \r
3976 to a valid user info handle.\r
3977 @retval EFI_INVALID_PARAMETER Info is NULL or InfoSize is NULL.\r
3978 \r
3979**/\r
3980EFI_STATUS\r
3981EFIAPI\r
3982UserProfileGetInfo (\r
3983 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3984 IN EFI_USER_PROFILE_HANDLE User,\r
3985 IN EFI_USER_INFO_HANDLE UserInfo,\r
3986 OUT EFI_USER_INFO *Info,\r
3987 IN OUT UINTN *InfoSize\r
3988 )\r
3989{\r
3990 EFI_STATUS Status;\r
3991\r
3992 if ((This == NULL) || (InfoSize == NULL)) {\r
3993 return EFI_INVALID_PARAMETER;\r
3994 }\r
3995\r
3996 if ((*InfoSize != 0) && (Info == NULL)) {\r
3997 return EFI_INVALID_PARAMETER;\r
3998 }\r
3999 \r
4000 if ((User == NULL) || (UserInfo == NULL)) {\r
4001 return EFI_NOT_FOUND;\r
4002 }\r
4003 \r
4004 Status = GetUserInfo (User, UserInfo, Info, InfoSize, TRUE);\r
4005 if (EFI_ERROR (Status)) {\r
4006 if (Status == EFI_BUFFER_TOO_SMALL) {\r
4007 return EFI_BUFFER_TOO_SMALL;\r
4008 }\r
4009 return EFI_ACCESS_DENIED;\r
4010 }\r
4011 return EFI_SUCCESS;\r
4012}\r
4013\r
4014\r
4015/**\r
4016 Add or update user information.\r
4017\r
4018 This function changes user information. If NULL is pointed to by UserInfo, then a new user \r
4019 information record is created and its handle is returned in UserInfo. Otherwise, the existing \r
4020 one is replaced.\r
4021 If EFI_USER_INFO_EXCLUSIVE is specified in Info and a user information record of the same \r
4022 type already exists in the user profile, then EFI_ACCESS_DENIED will be returned and UserInfo\r
4023 will point to the handle of the existing record.\r
4024\r
4025 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
4026 @param[in] User Handle of the user whose profile will be retrieved. \r
4027 @param[in, out] UserInfo Handle of the user information data record. \r
4028 @param[in] Info On entry, points to a buffer of at least *InfoSize bytes. On exit, \r
4029 holds the user information. If the buffer is too small to hold the \r
4030 information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is \r
4031 updated to contain the number of bytes actually required. \r
4032 @param[in] InfoSize On entry, points to the size of Info. On return, points to the size \r
4033 of the user information. \r
4034\r
4035 @retval EFI_SUCCESS Information returned successfully.\r
4036 @retval EFI_ACCESS_DENIED The record is exclusive.\r
4037 @retval EFI_SECURITY_VIOLATION The current user does not have permission to change the specified \r
4038 user profile or user information record.\r
4039 @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not \r
4040 refer to a valid user info handle.\r
4041 @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL. \r
4042**/\r
4043EFI_STATUS\r
4044EFIAPI\r
4045UserProfileSetInfo (\r
4046 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
4047 IN EFI_USER_PROFILE_HANDLE User,\r
4048 IN OUT EFI_USER_INFO_HANDLE *UserInfo,\r
4049 IN CONST EFI_USER_INFO *Info,\r
4050 IN UINTN InfoSize\r
4051 )\r
4052{\r
4053 EFI_STATUS Status;\r
4054\r
4055 if ((This == NULL) || (User == NULL) || (UserInfo == NULL) || (Info == NULL)) {\r
4056 return EFI_INVALID_PARAMETER;\r
4057 }\r
4058 \r
4059 //\r
4060 // Check the right of the current user.\r
4061 //\r
4062 if (User != mCurrentUser) {\r
4063 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
4064 if (*UserInfo != NULL) {\r
4065 //\r
4066 // Can't update info in other profiles without MANAGE right.\r
4067 //\r
4068 return EFI_SECURITY_VIOLATION;\r
4069 }\r
4070 \r
4071 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS)) {\r
4072 //\r
4073 // Can't add info into other profiles.\r
4074 //\r
4075 return EFI_SECURITY_VIOLATION;\r
4076 }\r
4077 }\r
4078 }\r
4079\r
4080 if (User == mCurrentUser) {\r
4081 if (CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_SELF)) {\r
4082 //\r
4083 // Only identify policy can be added/updated.\r
4084 //\r
4085 if (Info->InfoType != EFI_USER_INFO_IDENTITY_POLICY_RECORD) {\r
4086 return EFI_SECURITY_VIOLATION;\r
4087 }\r
4088 }\r
4089 }\r
4090 \r
4091 //\r
4092 // Modify user information.\r
4093 //\r
4094 Status = ModifyUserInfo (User, (EFI_USER_INFO **) UserInfo, Info, InfoSize);\r
4095 if (EFI_ERROR (Status)) {\r
4096 if (Status == EFI_ACCESS_DENIED) {\r
4097 return EFI_ACCESS_DENIED; \r
4098 }\r
4099 return EFI_SECURITY_VIOLATION;\r
4100 }\r
4101 return EFI_SUCCESS;\r
4102}\r
4103\r
4104\r
4105/**\r
4106 Called by credential provider to notify of information change.\r
4107\r
4108 This function allows the credential provider to notify the User Identity Manager when user status \r
4109 has changed while deselected.\r
4110 If the User Identity Manager doesn't support asynchronous changes in credentials, then this function \r
4111 should return EFI_UNSUPPORTED. \r
4112 If the User Identity Manager supports this, it will call User() to get the user identifier and then \r
4113 GetNextInfo() and GetInfo() in the User Credential Protocol to get all of the information from the \r
4114 credential and add it.\r
4115\r
4116 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
4117 @param[in] Changed Handle on which is installed an instance of the EFI_USER_CREDENTIAL_PROTOCOL \r
4118 where the user has changed.\r
4119\r
4120 @retval EFI_SUCCESS The User Identity Manager has handled the notification.\r
4121 @retval EFI_NOT_READY The function was called while the specified credential provider was not selected.\r
4122 @retval EFI_UNSUPPORTED The User Identity Manager doesn't support asynchronous notifications.\r
4123 \r
4124**/\r
4125EFI_STATUS\r
4126EFIAPI\r
4127UserProfileNotify (\r
4128 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
4129 IN EFI_HANDLE Changed\r
4130 )\r
4131{\r
4132 EFI_STATUS Status;\r
4133 EFI_USER_CREDENTIAL_PROTOCOL *Provider;\r
4134 EFI_USER_INFO_IDENTIFIER UserId;\r
4135 EFI_USER_INFO_HANDLE UserInfo;\r
4136 EFI_USER_INFO_HANDLE UserInfo2;\r
4137 UINTN InfoSize;\r
4138 EFI_USER_INFO *Info;\r
4139 USER_PROFILE_ENTRY *User;\r
4140\r
4141 if (This == NULL) {\r
4142 return EFI_INVALID_PARAMETER;\r
4143 }\r
4144 \r
4145 Status = gBS->HandleProtocol (\r
4146 Changed,\r
4147 &gEfiUserCredentialProtocolGuid,\r
4148 (VOID **) &Provider\r
4149 );\r
4150 if (EFI_ERROR (Status)) {\r
4151 return Status;\r
4152 }\r
4153\r
4154 Status = Provider->User (Provider, NULL, &UserId);\r
4155 if (EFI_ERROR (Status)) {\r
4156 return EFI_NOT_READY;\r
4157 }\r
4158\r
4159 //\r
4160 // Find user with the UserId.\r
4161 //\r
4162 User = NULL;\r
4163 while (TRUE) {\r
4164 //\r
4165 // Find next user profile.\r
4166 // \r
4167 Status = FindUserProfile (&User, TRUE, NULL);\r
4168 if (EFI_ERROR (Status)) {\r
4169 return Status;\r
4170 }\r
4171 \r
4172 //\r
4173 // Find the user information.\r
4174 //\r
4175 Info = NULL;\r
4176 FindUserInfoByType (User, &Info, EFI_USER_INFO_IDENTIFIER_RECORD);\r
4177 if (CompareMem ((UINT8 *) (Info + 1), UserId, sizeof (UserId)) == 0) {\r
4178 //\r
4179 // Found the infomation record. \r
4180 //\r
4181 break;\r
4182 }\r
4183 }\r
4184\r
4185 UserInfo = NULL;\r
4186 do {\r
4187 //\r
4188 // Get user info handle.\r
4189 //\r
4190 Status = Provider->GetNextInfo(Provider, &UserInfo);\r
4191 if (EFI_ERROR (Status)) {\r
4192 return EFI_SUCCESS;\r
4193 }\r
4194\r
4195 //\r
4196 // Get the user information from the user info handle.\r
4197 // \r
4198 InfoSize = 0;\r
4199 Status = Provider->GetInfo(Provider, UserInfo, NULL, &InfoSize);\r
4200 if (EFI_ERROR (Status)) {\r
4201 if (Status == EFI_BUFFER_TOO_SMALL) {\r
4202 Info = AllocateZeroPool (InfoSize);\r
4203 if (Info == NULL) {\r
4204 return EFI_OUT_OF_RESOURCES;\r
4205 }\r
4206 Status = Provider->GetInfo(Provider, UserInfo, Info, &InfoSize);\r
4207 if (EFI_ERROR (Status)) {\r
4208 FreePool (Info);\r
4209 break;\r
4210 }\r
4211 }\r
4212 break;\r
4213 }\r
4214\r
4215 //\r
4216 // Save the user information.\r
4217 // \r
4218 UserInfo2 = NULL;\r
4219 Status = UserProfileSetInfo (&gUserIdentifyManager, (EFI_USER_PROFILE_HANDLE)User, &UserInfo2, Info, InfoSize);\r
4220 FreePool (Info);\r
4221 if (EFI_ERROR (Status)) {\r
4222 break;\r
4223 }\r
4224 } while (TRUE);\r
4225 \r
4226 return Status;\r
4227}\r
4228\r
4229\r
4230/**\r
4231 Delete user information.\r
4232\r
4233 Delete the user information attached to the user profile specified by the UserInfo.\r
4234\r
4235 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
4236 @param[in] User Handle of the user whose information will be deleted.\r
4237 @param[in] UserInfo Handle of the user information to remove.\r
4238\r
4239 @retval EFI_SUCCESS User information deleted successfully.\r
4240 @retval EFI_NOT_FOUND User information record UserInfo does not exist in the user profile.\r
4241 @retval EFI_ACCESS_DENIED The current user does not have permission to delete this user information. \r
4242 \r
4243**/\r
4244EFI_STATUS\r
4245EFIAPI\r
4246UserProfileDeleteInfo (\r
4247 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
4248 IN EFI_USER_PROFILE_HANDLE User,\r
4249 IN EFI_USER_INFO_HANDLE UserInfo\r
4250 )\r
4251{\r
4252 EFI_STATUS Status;\r
4253\r
4254 if (This == NULL) {\r
4255 return EFI_INVALID_PARAMETER;\r
4256 }\r
4257 \r
4258 //\r
4259 // Check the right of the current user.\r
4260 //\r
4261 if (User != mCurrentUser) {\r
4262 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
4263 return EFI_ACCESS_DENIED;\r
4264 }\r
4265 }\r
4266 \r
4267 //\r
4268 // Delete user information.\r
4269 //\r
4270 Status = DelUserInfo (User, UserInfo, TRUE);\r
4271 if (EFI_ERROR (Status)) {\r
4272 if (Status == EFI_NOT_FOUND) {\r
4273 return EFI_NOT_FOUND;\r
4274 }\r
4275 return EFI_ACCESS_DENIED;\r
4276 } \r
4277 return EFI_SUCCESS;\r
4278}\r
4279\r
4280\r
4281/**\r
4282 Enumerate user information of all the enrolled users on the platform.\r
4283\r
4284 This function returns the next user information record. To retrieve the first user \r
4285 information record handle, point UserInfo at a NULL. Each subsequent call will retrieve \r
4286 another user information record handle until there are no more, at which point UserInfo \r
4287 will point to NULL. \r
4288\r
4289 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
4290 @param[in] User Handle of the user whose information will be deleted.\r
4291 @param[in, out] UserInfo Handle of the user information to remove.\r
4292\r
4293 @retval EFI_SUCCESS User information returned.\r
4294 @retval EFI_NOT_FOUND No more user information found.\r
4295 @retval EFI_INVALID_PARAMETER UserInfo is NULL.\r
4296 \r
4297**/\r
4298EFI_STATUS\r
4299EFIAPI\r
4300UserProfileGetNextInfo (\r
4301 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
4302 IN EFI_USER_PROFILE_HANDLE User,\r
4303 IN OUT EFI_USER_INFO_HANDLE *UserInfo\r
4304 )\r
4305{\r
4306 if ((This == NULL) || (UserInfo == NULL)) {\r
4307 return EFI_INVALID_PARAMETER;\r
4308 }\r
4309 //\r
4310 // Get next user information entry.\r
4311 //\r
4312 return FindUserInfo (User, (EFI_USER_INFO **) UserInfo, TRUE, NULL);\r
4313}\r
4314\r
4315\r
4316/**\r
4317 Main entry for this driver.\r
4318\r
4319 @param[in] ImageHandle Image handle this driver.\r
4320 @param[in] SystemTable Pointer to SystemTable.\r
4321\r
4322 @retval EFI_SUCESS This function always complete successfully.\r
4323\r
4324**/\r
4325EFI_STATUS\r
4326EFIAPI\r
4327UserIdentifyManagerInit (\r
4328 IN EFI_HANDLE ImageHandle,\r
4329 IN EFI_SYSTEM_TABLE *SystemTable\r
4330 )\r
4331{\r
4332\r
4333 EFI_STATUS Status;\r
4334\r
4335 //\r
4336 // Initiate form browser.\r
4337 //\r
4338 InitFormBrowser ();\r
4339\r
4340 //\r
4341 // Install protocol interfaces for the User Identity Manager.\r
4342 //\r
4343 Status = gBS->InstallProtocolInterface (\r
4344 &mCallbackInfo->DriverHandle,\r
4345 &gEfiUserManagerProtocolGuid,\r
4346 EFI_NATIVE_INTERFACE,\r
4347 &gUserIdentifyManager\r
4348 );\r
4349 ASSERT_EFI_ERROR (Status); \r
4350\r
4351 LoadDeferredImageInit (ImageHandle);\r
4352 return EFI_SUCCESS;\r
4353}\r
4354\r
4355\r