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