]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManager.c
Add security package to repository.
[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
2322 @param[in] Provider Points to the identifir of credential provider.\r
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
2343 EFI_USER_INFO *IdInfo;\r
2344\r
2345 if (Provider == NULL) {\r
2346 return EFI_INVALID_PARAMETER;\r
2347 }\r
2348 \r
2349 //\r
2350 // Check the user ID identified by the specified credential provider.\r
2351 //\r
2352 for (Index = 0; Index < mProviderDb->Count; Index++) {\r
2353 //\r
2354 // Check credential provider class.\r
2355 //\r
2356 UserCredential = mProviderDb->Provider[Index];\r
2357 if (CompareGuid (&UserCredential->Identifier, Provider)) {\r
2358 Status = UserCredential->Select (UserCredential, &AutoLogon);\r
2359 if (EFI_ERROR (Status)) {\r
2360 return Status;\r
2361 }\r
2362\r
2363 if ((AutoLogon & EFI_CREDENTIAL_LOGON_FLAG_AUTO) == 0) {\r
2364 //\r
2365 // Get credential provider form.\r
2366 //\r
2367 Status = UserCredential->Form (\r
2368 UserCredential, \r
2369 &HiiHandle, \r
2370 &FormSetId, \r
2371 &FormId\r
2372 );\r
2373 if (!EFI_ERROR (Status)) { \r
2374 //\r
2375 // Send form to get user input.\r
2376 //\r
2377 Status = mCallbackInfo->FormBrowser2->SendForm (\r
2378 mCallbackInfo->FormBrowser2,\r
2379 &HiiHandle,\r
2380 1,\r
2381 &FormSetId,\r
2382 FormId,\r
2383 NULL,\r
2384 NULL\r
2385 );\r
2386 if (EFI_ERROR (Status)) {\r
2387 return Status;\r
2388 } \r
2389 } \r
2390 }\r
2391\r
2392 Status = UserCredential->User (UserCredential, User, &UserId);\r
2393 if (EFI_ERROR (Status)) {\r
2394 return Status;\r
2395 }\r
2396\r
2397 Status = UserCredential->Deselect (UserCredential);\r
2398 if (EFI_ERROR (Status)) {\r
2399 return Status;\r
2400 }\r
2401\r
2402 if (User == NULL) {\r
2403 return EFI_SUCCESS;\r
2404 }\r
2405 \r
2406 //\r
2407 // Get user ID information.\r
2408 //\r
2409 IdInfo = NULL;\r
2410 Status = FindUserInfoByType (User, &IdInfo, EFI_USER_INFO_IDENTIFIER_RECORD);\r
2411 ASSERT (IdInfo != NULL);\r
2412\r
2413 if (CompareMem ((UINT8 *) (IdInfo + 1), UserId, sizeof (EFI_USER_INFO_IDENTIFIER)) != 0) {\r
2414 //\r
2415 // One user name is selected, but the other's credential is given. Here no user passed.\r
2416 //\r
2417 break;\r
2418 }\r
2419 return EFI_SUCCESS;\r
2420 }\r
2421 }\r
2422\r
2423 return EFI_NOT_FOUND;\r
2424}\r
2425\r
2426\r
2427/**\r
2428 Update user information when user is logon on successfully.\r
2429\r
2430 @param[in] User Points to user profile.\r
2431\r
2432 @retval EFI_SUCCESS Update user information successfully.\r
2433 @retval Others Fail to update user information.\r
2434\r
2435**/\r
2436EFI_STATUS\r
2437UpdateUserInfo (\r
2438 IN USER_PROFILE_ENTRY *User\r
2439 )\r
2440{\r
2441 EFI_STATUS Status;\r
2442 EFI_USER_INFO *Info;\r
2443 EFI_USER_INFO *NewInfo;\r
2444 EFI_USER_INFO_CREATE_DATE Date;\r
2445 EFI_USER_INFO_USAGE_COUNT UsageCount;\r
2446 UINTN InfoLen;\r
2447\r
2448 //\r
2449 // Allocate a buffer to update user's date record and usage record.\r
2450 //\r
2451 InfoLen = MAX (sizeof (EFI_USER_INFO_CREATE_DATE), sizeof (EFI_USER_INFO_USAGE_COUNT));\r
2452 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + InfoLen);\r
2453 if (Info == NULL) {\r
2454 return EFI_OUT_OF_RESOURCES;\r
2455 }\r
2456 \r
2457 //\r
2458 // Check create date record.\r
2459 //\r
2460 NewInfo = NULL;\r
2461 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_CREATE_DATE_RECORD);\r
2462 if (Status == EFI_NOT_FOUND) {\r
2463 Info->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD;\r
2464 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2465 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE);\r
2466 Status = gRT->GetTime (&Date, NULL);\r
2467 if (EFI_ERROR (Status)) {\r
2468 FreePool (Info);\r
2469 return Status;\r
2470 }\r
2471\r
2472 CopyMem ((UINT8 *) (Info + 1), &Date, sizeof (EFI_USER_INFO_CREATE_DATE));\r
2473 NewInfo = NULL;\r
2474 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2475 if (EFI_ERROR (Status)) {\r
2476 FreePool (Info);\r
2477 return Status;\r
2478 }\r
2479 }\r
2480 \r
2481 //\r
2482 // Update usage date record.\r
2483 //\r
2484 NewInfo = NULL;\r
2485 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_USAGE_DATE_RECORD);\r
2486 if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {\r
2487 Info->InfoType = EFI_USER_INFO_USAGE_DATE_RECORD;\r
2488 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2489 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_DATE);\r
2490 Status = gRT->GetTime (&Date, NULL);\r
2491 if (EFI_ERROR (Status)) {\r
2492 FreePool (Info);\r
2493 return Status;\r
2494 }\r
2495\r
2496 CopyMem ((UINT8 *) (Info + 1), &Date, sizeof (EFI_USER_INFO_USAGE_DATE));\r
2497 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2498 if (EFI_ERROR (Status)) {\r
2499 FreePool (Info);\r
2500 return Status;\r
2501 }\r
2502 }\r
2503 \r
2504 //\r
2505 // Update usage count record.\r
2506 //\r
2507 UsageCount = 0;\r
2508 NewInfo = NULL;\r
2509 Status = FindUserInfoByType (User, &NewInfo, EFI_USER_INFO_USAGE_COUNT_RECORD);\r
2510 //\r
2511 // Get usage count.\r
2512 //\r
2513 if (Status == EFI_SUCCESS) {\r
2514 CopyMem (&UsageCount, (UINT8 *) (NewInfo + 1), sizeof (EFI_USER_INFO_USAGE_COUNT));\r
2515 }\r
2516\r
2517 UsageCount++;\r
2518 if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {\r
2519 Info->InfoType = EFI_USER_INFO_USAGE_COUNT_RECORD;\r
2520 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;\r
2521 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_USAGE_COUNT);\r
2522 CopyMem ((UINT8 *) (Info + 1), &UsageCount, sizeof (EFI_USER_INFO_USAGE_COUNT));\r
2523 Status = ModifyUserInfo (User, &NewInfo, Info, Info->InfoSize);\r
2524 if (EFI_ERROR (Status)) {\r
2525 FreePool (Info);\r
2526 return Status;\r
2527 }\r
2528 }\r
2529\r
2530 FreePool (Info);\r
2531 return EFI_SUCCESS;\r
2532}\r
2533\r
2534\r
2535/**\r
2536 Add a credenetial provider item in form.\r
2537\r
2538 @param[in] ProviderGuid Points to the identifir of credential provider.\r
2539 @param[in] OpCodeHandle Points to container for dynamic created opcodes.\r
2540\r
2541**/\r
2542VOID\r
2543AddProviderSelection (\r
2544 IN EFI_GUID *ProviderGuid,\r
2545 IN VOID *OpCodeHandle\r
2546 )\r
2547{\r
2548 EFI_HII_HANDLE HiiHandle;\r
2549 EFI_STRING_ID ProvID;\r
2550 CHAR16 *ProvStr;\r
2551 UINTN Index;\r
2552 EFI_USER_CREDENTIAL_PROTOCOL *UserCredential;\r
2553\r
2554 for (Index = 0; Index < mProviderDb->Count; Index++) {\r
2555 UserCredential = mProviderDb->Provider[Index];\r
2556 if (CompareGuid (&UserCredential->Identifier, ProviderGuid)) {\r
2557 //\r
2558 // Add credential provider selection.\r
2559 //\r
2560 UserCredential->Title (UserCredential, &HiiHandle, &ProvID);\r
2561 ProvStr = HiiGetString (HiiHandle, ProvID, NULL);\r
2562 if (ProvStr == NULL) {\r
2563 continue ;\r
2564 }\r
2565 ProvID = HiiSetString (mCallbackInfo->HiiHandle, 0, ProvStr, NULL);\r
2566 FreePool (ProvStr);\r
2567 HiiCreateActionOpCode (\r
2568 OpCodeHandle, // Container for dynamic created opcodes\r
2569 (EFI_QUESTION_ID)(LABEL_PROVIDER_NAME + Index), // Question ID\r
2570 ProvID, // Prompt text\r
2571 STRING_TOKEN (STR_NULL_STRING), // Help text\r
2572 EFI_IFR_FLAG_CALLBACK, // Question flag\r
2573 0 // Action String ID\r
2574 );\r
2575 break;\r
2576 }\r
2577 }\r
2578}\r
2579\r
2580\r
2581/**\r
2582 Add a username item in form.\r
2583\r
2584 @param[in] Index The index of the user in the user name list.\r
2585 @param[in] User Points to the user profile whose username is added. \r
2586 @param[in] OpCodeHandle Points to container for dynamic created opcodes.\r
2587\r
2588 @retval EFI_SUCCESS Add a username successfully.\r
2589 @retval Others Fail to add a username.\r
2590\r
2591**/\r
2592EFI_STATUS\r
2593AddUserSelection (\r
2594 IN UINT16 Index,\r
2595 IN USER_PROFILE_ENTRY *User,\r
2596 IN VOID *OpCodeHandle\r
2597 )\r
2598{\r
2599 EFI_STRING_ID UserName;\r
2600 EFI_STATUS Status;\r
2601 EFI_USER_INFO *UserInfo;\r
2602\r
2603 UserInfo = NULL;\r
2604 Status = FindUserInfoByType (User, &UserInfo, EFI_USER_INFO_NAME_RECORD);\r
2605 if (EFI_ERROR (Status)) {\r
2606 return Status;\r
2607 }\r
2608 \r
2609 //\r
2610 // Add user name selection.\r
2611 //\r
2612 UserName = HiiSetString (mCallbackInfo->HiiHandle, 0, (EFI_STRING) (UserInfo + 1), NULL);\r
2613 if (UserName == 0) {\r
2614 return EFI_OUT_OF_RESOURCES;\r
2615 }\r
2616\r
2617 HiiCreateGotoOpCode (\r
2618 OpCodeHandle, // Container for dynamic created opcodes\r
2619 FORMID_PROVIDER_FORM, // Target Form ID\r
2620 UserName, // Prompt text\r
2621 STRING_TOKEN (STR_NULL_STRING), // Help text\r
2622 EFI_IFR_FLAG_CALLBACK, // Question flag\r
2623 (UINT16) Index // Question ID\r
2624 );\r
2625\r
2626 return EFI_SUCCESS;\r
2627}\r
2628\r
2629\r
2630/**\r
2631 Identify the user whose identity policy does not contain the operator 'OR'.\r
2632 \r
2633 @param[in] User Points to the user profile.\r
2634\r
2635 @retval EFI_SUCCESS The specified user is identified successfully.\r
2636 @retval Others Fail to identify the user.\r
2637 \r
2638**/\r
2639EFI_STATUS\r
2640IdentifyAndTypeUser (\r
2641 IN USER_PROFILE_ENTRY *User\r
2642 )\r
2643{\r
2644 EFI_STATUS Status;\r
2645 EFI_USER_INFO *IdentifyInfo;\r
2646 BOOLEAN Success;\r
2647 UINTN TotalLen;\r
2648 UINTN ValueLen;\r
2649 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
2650\r
2651 //\r
2652 // Get user identify policy information.\r
2653 //\r
2654 IdentifyInfo = NULL;\r
2655 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
2656 if (EFI_ERROR (Status)) {\r
2657 return Status;\r
2658 }\r
2659 ASSERT (IdentifyInfo != NULL);\r
2660 \r
2661 //\r
2662 // Check each part of identification policy expression.\r
2663 //\r
2664 Success = FALSE;\r
2665 TotalLen = 0;\r
2666 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
2667 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
2668 ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
2669 switch (Identity->Type) {\r
2670\r
2671 case EFI_USER_INFO_IDENTITY_FALSE:\r
2672 //\r
2673 // Check False option.\r
2674 //\r
2675 Success = FALSE;\r
2676 break;\r
2677\r
2678 case EFI_USER_INFO_IDENTITY_TRUE:\r
2679 //\r
2680 // Check True option.\r
2681 //\r
2682 Success = TRUE;\r
2683 break;\r
2684\r
2685 case EFI_USER_INFO_IDENTITY_NOT:\r
2686 //\r
2687 // Check negative operation.\r
2688 //\r
2689 break;\r
2690\r
2691 case EFI_USER_INFO_IDENTITY_AND:\r
2692 //\r
2693 // Check and operation.\r
2694 //\r
2695 if (!Success) {\r
2696 return EFI_NOT_READY;\r
2697 }\r
2698\r
2699 Success = FALSE;\r
2700 break;\r
2701\r
2702 case EFI_USER_INFO_IDENTITY_OR:\r
2703 //\r
2704 // Check or operation.\r
2705 //\r
2706 if (Success) {\r
2707 return EFI_SUCCESS;\r
2708 }\r
2709 break;\r
2710\r
2711 case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:\r
2712 //\r
2713 // Check credential provider by type.\r
2714 //\r
2715 break;\r
2716\r
2717 case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:\r
2718 //\r
2719 // Check credential provider by ID.\r
2720 //\r
2721 if (ValueLen != sizeof (EFI_GUID)) {\r
2722 return EFI_INVALID_PARAMETER;\r
2723 }\r
2724\r
2725 Status = IdentifyByProviderId (User, (EFI_GUID *) (Identity + 1));\r
2726 if (EFI_ERROR (Status)) {\r
2727 return Status;\r
2728 }\r
2729\r
2730 Success = TRUE;\r
2731 break;\r
2732\r
2733 default:\r
2734 return EFI_INVALID_PARAMETER;\r
2735 break;\r
2736 }\r
2737\r
2738 TotalLen += Identity->Length;\r
2739 }\r
2740\r
2741 if (TotalLen != IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
2742 return EFI_INVALID_PARAMETER;\r
2743 }\r
2744\r
2745 if (!Success) {\r
2746 return EFI_NOT_READY;\r
2747 }\r
2748\r
2749 return EFI_SUCCESS;\r
2750}\r
2751\r
2752\r
2753/**\r
2754 Identify the user whose identity policy does not contain the operator 'AND'.\r
2755 \r
2756 @param[in] User Points to the user profile.\r
2757\r
2758 @retval EFI_SUCCESS The specified user is identified successfully.\r
2759 @retval Others Fail to identify the user.\r
2760 \r
2761**/\r
2762EFI_STATUS\r
2763IdentifyOrTypeUser (\r
2764 IN USER_PROFILE_ENTRY *User\r
2765 )\r
2766{\r
2767 EFI_STATUS Status;\r
2768 EFI_USER_INFO *IdentifyInfo;\r
2769 UINTN TotalLen;\r
2770 UINTN ValueLen;\r
2771 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
2772 VOID *StartOpCodeHandle;\r
2773 VOID *EndOpCodeHandle;\r
2774 EFI_IFR_GUID_LABEL *StartLabel;\r
2775 EFI_IFR_GUID_LABEL *EndLabel;\r
2776\r
2777 //\r
2778 // Get user identify policy information.\r
2779 //\r
2780 IdentifyInfo = NULL;\r
2781 Status = FindUserInfoByType (User, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
2782 if (EFI_ERROR (Status)) {\r
2783 return Status;\r
2784 }\r
2785 ASSERT (IdentifyInfo != NULL);\r
2786 \r
2787 //\r
2788 // Initialize the container for dynamic opcodes.\r
2789 //\r
2790 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2791 ASSERT (StartOpCodeHandle != NULL);\r
2792\r
2793 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2794 ASSERT (EndOpCodeHandle != NULL);\r
2795\r
2796 //\r
2797 // Create Hii Extend Label OpCode.\r
2798 //\r
2799 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2800 StartOpCodeHandle,\r
2801 &gEfiIfrTianoGuid,\r
2802 NULL,\r
2803 sizeof (EFI_IFR_GUID_LABEL)\r
2804 );\r
2805 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2806 StartLabel->Number = LABEL_PROVIDER_NAME;\r
2807\r
2808 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2809 EndOpCodeHandle,\r
2810 &gEfiIfrTianoGuid,\r
2811 NULL,\r
2812 sizeof (EFI_IFR_GUID_LABEL)\r
2813 );\r
2814 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2815 EndLabel->Number = LABEL_END;\r
2816\r
2817 //\r
2818 // Add the providers that exists in the user's policy.\r
2819 //\r
2820 TotalLen = 0;\r
2821 while (TotalLen < IdentifyInfo->InfoSize - sizeof (EFI_USER_INFO)) {\r
2822 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1) + TotalLen);\r
2823 ValueLen = Identity->Length - sizeof (EFI_USER_INFO_IDENTITY_POLICY);\r
2824 if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {\r
2825 AddProviderSelection ((EFI_GUID *) (Identity + 1), StartOpCodeHandle);\r
2826 }\r
2827\r
2828 TotalLen += Identity->Length;\r
2829 }\r
2830\r
2831 HiiUpdateForm (\r
2832 mCallbackInfo->HiiHandle, // HII handle\r
2833 &mUserManagerGuid, // Formset GUID\r
2834 FORMID_PROVIDER_FORM, // Form ID\r
2835 StartOpCodeHandle, // Label for where to insert opcodes\r
2836 EndOpCodeHandle // Replace data\r
2837 );\r
2838\r
2839 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
2840 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
2841\r
2842 return EFI_SUCCESS;\r
2843}\r
2844\r
2845\r
2846/**\r
2847 This function processes the results of changes in configuration.\r
2848\r
2849 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
2850 @param Action Specifies the type of action taken by the browser.\r
2851 @param QuestionId A unique value which is sent to the original\r
2852 exporting driver so that it can identify the type\r
2853 of data to expect.\r
2854 @param Type The type of value for the question.\r
2855 @param Value A pointer to the data being sent to the original\r
2856 exporting driver.\r
2857 @param ActionRequest On return, points to the action requested by the\r
2858 callback function.\r
2859\r
2860 @retval EFI_SUCCESS The callback successfully handled the action.\r
2861 @retval Others Fail to handle the action.\r
2862\r
2863**/\r
2864EFI_STATUS\r
2865EFIAPI\r
2866UserIdentifyManagerCallback (\r
2867 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
2868 IN EFI_BROWSER_ACTION Action,\r
2869 IN EFI_QUESTION_ID QuestionId,\r
2870 IN UINT8 Type,\r
2871 IN EFI_IFR_TYPE_VALUE *Value,\r
2872 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
2873 )\r
2874{\r
2875 EFI_STATUS Status;\r
2876 USER_PROFILE_ENTRY *User;\r
2877 UINT8 PolicyType;\r
2878 UINT16 Index;\r
2879 VOID *StartOpCodeHandle;\r
2880 VOID *EndOpCodeHandle;\r
2881 EFI_IFR_GUID_LABEL *StartLabel;\r
2882 EFI_IFR_GUID_LABEL *EndLabel;\r
2883\r
2884 Status = EFI_SUCCESS;\r
2885\r
2886 switch (Action) {\r
2887 case EFI_BROWSER_ACTION_FORM_OPEN:\r
2888 {\r
2889 //\r
2890 // Update user Form when user Form is opened.\r
2891 // This will be done only in FORM_OPEN CallBack of question with FORM_OPEN_QUESTION_ID from user Form.\r
2892 //\r
2893 if (QuestionId != FORM_OPEN_QUESTION_ID) {\r
2894 return EFI_SUCCESS;\r
2895 }\r
2896 \r
2897 //\r
2898 // Initialize the container for dynamic opcodes.\r
2899 //\r
2900 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2901 ASSERT (StartOpCodeHandle != NULL);\r
2902 \r
2903 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2904 ASSERT (EndOpCodeHandle != NULL);\r
2905 \r
2906 //\r
2907 // Create Hii Extend Label OpCode.\r
2908 //\r
2909 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2910 StartOpCodeHandle,\r
2911 &gEfiIfrTianoGuid,\r
2912 NULL,\r
2913 sizeof (EFI_IFR_GUID_LABEL)\r
2914 );\r
2915 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2916 StartLabel->Number = LABEL_USER_NAME;\r
2917 \r
2918 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
2919 EndOpCodeHandle,\r
2920 &gEfiIfrTianoGuid,\r
2921 NULL,\r
2922 sizeof (EFI_IFR_GUID_LABEL)\r
2923 );\r
2924 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
2925 EndLabel->Number = LABEL_END;\r
2926 \r
2927 //\r
2928 // Add all the user profile in the user profile database.\r
2929 //\r
2930 for (Index = 0; Index < mUserProfileDb->UserProfileNum; Index++) {\r
2931 User = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[Index];\r
2932 AddUserSelection ((UINT16)(LABEL_USER_NAME + Index), User, StartOpCodeHandle);\r
2933 }\r
2934 \r
2935 HiiUpdateForm (\r
2936 mCallbackInfo->HiiHandle, // HII handle\r
2937 &mUserManagerGuid, // Formset GUID\r
2938 FORMID_USER_FORM, // Form ID\r
2939 StartOpCodeHandle, // Label for where to insert opcodes\r
2940 EndOpCodeHandle // Replace data\r
2941 );\r
2942 \r
2943 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
2944 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
2945 \r
2946 return EFI_SUCCESS;\r
2947 }\r
2948 break;\r
2949\r
2950 case EFI_BROWSER_ACTION_FORM_CLOSE:\r
2951 Status = EFI_SUCCESS;\r
2952 break;\r
2953\r
2954 case EFI_BROWSER_ACTION_CHANGING:\r
2955 {\r
2956 if (QuestionId >= LABEL_PROVIDER_NAME) {\r
2957 //\r
2958 // QuestionId comes from the second Form (Select a Credential Provider if identity \r
2959 // policy is OR type). Identify the user by the selected provider.\r
2960 //\r
2961 Status = IdentifyByProviderId (mCurrentUser, &mProviderDb->Provider[QuestionId & 0xFFF]->Identifier);\r
2962 if (Status == EFI_SUCCESS) {\r
2963 mIdentified = TRUE;\r
2964 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
2965 }\r
2966 return EFI_SUCCESS;\r
2967 }\r
2968\r
2969 //\r
2970 // QuestionId comes from the first Form (Select a user to identify).\r
2971 //\r
2972 User = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[QuestionId & 0xFFF];\r
2973 Status = GetIdentifyType (User, &PolicyType);\r
2974 if (EFI_ERROR (Status)) {\r
2975 return Status;\r
2976 }\r
2977\r
2978 if (PolicyType == EFI_USER_INFO_IDENTITY_OR) {\r
2979 //\r
2980 // Identify the user by "OR" logical.\r
2981 //\r
2982 Status = IdentifyOrTypeUser (User);\r
2983 if (EFI_ERROR (Status)) {\r
2984 return Status;\r
2985 }\r
2986\r
2987 mCurrentUser = (EFI_USER_PROFILE_HANDLE) User;\r
2988 } else {\r
2989 //\r
2990 // Identify the user by "AND" logical.\r
2991 //\r
2992 Status = IdentifyAndTypeUser (User);\r
2993 if (EFI_ERROR (Status)) {\r
2994 return Status;\r
2995 }\r
2996\r
2997 mCurrentUser = (EFI_USER_PROFILE_HANDLE) User;\r
2998 mIdentified = TRUE;\r
2999 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
3000 }\r
3001 }\r
3002 break;\r
3003\r
3004 default:\r
3005 //\r
3006 // All other action return unsupported.\r
3007 //\r
3008 Status = EFI_UNSUPPORTED;\r
3009 break;\r
3010 }\r
3011\r
3012\r
3013 return Status;\r
3014}\r
3015\r
3016\r
3017/**\r
3018 This function construct user profile database from user data saved in the Flash.\r
3019 If no user is found in Flash, add one default user "administrator" in the user \r
3020 profile database.\r
3021\r
3022 @retval EFI_SUCCESS Init user profile database successfully.\r
3023 @retval Others Fail to init user profile database.\r
3024 \r
3025**/\r
3026EFI_STATUS\r
3027InitUserProfileDb (\r
3028 VOID\r
3029 )\r
3030{\r
3031 EFI_STATUS Status;\r
3032 UINT8 *VarData;\r
3033 UINTN VarSize;\r
3034 UINTN CurVarSize;\r
3035 CHAR16 VarName[10];\r
3036 UINTN Index;\r
3037 UINT32 VarAttr;\r
3038\r
3039 if (mUserProfileDb != NULL) {\r
3040 //\r
3041 // The user profiles had been already initialized.\r
3042 //\r
3043 return EFI_SUCCESS;\r
3044 }\r
3045\r
3046 //\r
3047 // Init user profile database structure.\r
3048 //\r
3049 if (!ExpandUsermUserProfileDb ()) {\r
3050 return EFI_OUT_OF_RESOURCES;\r
3051 }\r
3052\r
3053 CurVarSize = DEFAULT_PROFILE_SIZE;\r
3054 VarData = AllocateZeroPool (CurVarSize);\r
3055 if (VarData == NULL) {\r
3056 return EFI_OUT_OF_RESOURCES;\r
3057 }\r
3058 \r
3059 //\r
3060 // Get all user proifle entries.\r
3061 //\r
3062 Index = 0;\r
3063 while (TRUE) {\r
3064 //\r
3065 // Get variable name.\r
3066 //\r
3067 UnicodeSPrint (\r
3068 VarName, \r
3069 sizeof (VarName),\r
3070 L"User%04x", \r
3071 Index\r
3072 );\r
3073 Index++;\r
3074\r
3075 //\r
3076 // Get variable value.\r
3077 //\r
3078 VarSize = CurVarSize;\r
3079 Status = gRT->GetVariable (VarName, &mUserManagerGuid, &VarAttr, &VarSize, VarData);\r
3080 if (Status == EFI_BUFFER_TOO_SMALL) {\r
3081 FreePool (VarData);\r
3082 VarData = AllocatePool (VarSize);\r
3083 if (VarData == NULL) {\r
3084 Status = EFI_OUT_OF_RESOURCES;\r
3085 break;\r
3086 }\r
3087\r
3088 CurVarSize = VarSize;\r
3089 Status = gRT->GetVariable (VarName, &mUserManagerGuid, &VarAttr, &VarSize, VarData);\r
3090 }\r
3091\r
3092 if (EFI_ERROR (Status)) {\r
3093 if (Status == EFI_NOT_FOUND) {\r
3094 Status = EFI_SUCCESS;\r
3095 }\r
3096 break;\r
3097 }\r
3098 \r
3099 //\r
3100 // Check variable attributes.\r
3101 //\r
3102 if (VarAttr != (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)) {\r
3103 Status = gRT->SetVariable (VarName, &mUserManagerGuid, VarAttr, 0, NULL);\r
3104 continue;\r
3105 }\r
3106 \r
3107 //\r
3108 // Add user profile to the user profile database.\r
3109 //\r
3110 Status = AddUserProfile (NULL, VarSize, VarData, FALSE);\r
3111 if (EFI_ERROR (Status)) {\r
3112 if (Status == EFI_SECURITY_VIOLATION) {\r
3113 //\r
3114 // Delete invalid user profile\r
3115 //\r
3116 gRT->SetVariable (VarName, &mUserManagerGuid, VarAttr, 0, NULL);\r
3117 } else if (Status == EFI_OUT_OF_RESOURCES) {\r
3118 break;\r
3119 }\r
3120 } else {\r
3121 //\r
3122 // Delete and save the profile again if some invalid profiles are deleted.\r
3123 //\r
3124 if (mUserProfileDb->UserProfileNum < Index) {\r
3125 gRT->SetVariable (VarName, &mUserManagerGuid, VarAttr, 0, NULL);\r
3126 SaveNvUserProfile (mUserProfileDb->UserProfile[mUserProfileDb->UserProfileNum - 1], FALSE);\r
3127 }\r
3128 }\r
3129 }\r
3130\r
3131 if (VarData != NULL) {\r
3132 FreePool (VarData);\r
3133 }\r
3134\r
3135 if (EFI_ERROR (Status)) {\r
3136 return Status;\r
3137 }\r
3138 \r
3139 //\r
3140 // Check whether the user profile database is empty.\r
3141 //\r
3142 if (mUserProfileDb->UserProfileNum == 0) {\r
3143 Status = AddDefaultUserProfile ();\r
3144 }\r
3145\r
3146 return Status;\r
3147}\r
3148\r
3149\r
3150/**\r
3151 This function collects all the credential providers and saves to mProviderDb.\r
3152\r
3153 @retval EFI_SUCCESS Collect credential providers successfully.\r
3154 @retval Others Fail to collect credential providers.\r
3155\r
3156**/\r
3157EFI_STATUS\r
3158InitProviderInfo (\r
3159 VOID\r
3160 )\r
3161{\r
3162 EFI_STATUS Status;\r
3163 UINTN HandleCount;\r
3164 EFI_HANDLE *HandleBuf;\r
3165 UINTN Index; \r
3166\r
3167 if (mProviderDb != NULL) {\r
3168 //\r
3169 // The credential providers had been collected before.\r
3170 //\r
3171 return EFI_SUCCESS;\r
3172 }\r
3173\r
3174 //\r
3175 // Try to find all the user credential provider driver.\r
3176 //\r
3177 HandleCount = 0;\r
3178 HandleBuf = NULL;\r
3179 Status = gBS->LocateHandleBuffer (\r
3180 ByProtocol,\r
3181 &gEfiUserCredentialProtocolGuid,\r
3182 NULL,\r
3183 &HandleCount,\r
3184 &HandleBuf\r
3185 );\r
3186 if (EFI_ERROR (Status)) {\r
3187 return Status;\r
3188 }\r
3189\r
3190 //\r
3191 // Get provider infomation.\r
3192 //\r
3193 mProviderDb = AllocateZeroPool (\r
3194 sizeof (CREDENTIAL_PROVIDER_INFO) - \r
3195 sizeof (EFI_USER_CREDENTIAL_PROTOCOL *) + \r
3196 HandleCount * sizeof (EFI_USER_CREDENTIAL_PROTOCOL *)\r
3197 );\r
3198 if (mProviderDb == NULL) {\r
3199 FreePool (HandleBuf);\r
3200 return EFI_OUT_OF_RESOURCES;\r
3201 }\r
3202\r
3203 mProviderDb->Count = HandleCount;\r
3204 for (Index = 0; Index < HandleCount; Index++) {\r
3205 Status = gBS->HandleProtocol (\r
3206 HandleBuf[Index],\r
3207 &gEfiUserCredentialProtocolGuid,\r
3208 (VOID **) &mProviderDb->Provider[Index]\r
3209 );\r
3210 if (EFI_ERROR (Status)) {\r
3211 FreePool (HandleBuf);\r
3212 FreePool (mProviderDb);\r
3213 mProviderDb = NULL;\r
3214 return Status;\r
3215 }\r
3216 }\r
3217\r
3218 FreePool (HandleBuf);\r
3219 return EFI_SUCCESS;\r
3220}\r
3221\r
3222\r
3223/**\r
3224 This function allows a caller to extract the current configuration for one\r
3225 or more named elements from the target driver.\r
3226\r
3227\r
3228 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
3229 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
3230 @param Progress On return, points to a character in the Request string.\r
3231 Points to the string's null terminator if request was successful.\r
3232 Points to the most recent '&' before the first failing name/value\r
3233 pair (or the beginning of the string if the failure is in the\r
3234 first name/value pair) if the request was not successful.\r
3235 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
3236 has all values filled in for the names in the Request string.\r
3237 String to be allocated by the called function.\r
3238\r
3239 @retval EFI_SUCCESS The Results is filled with the requested values.\r
3240 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
3241 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
3242 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
3243\r
3244**/\r
3245EFI_STATUS\r
3246EFIAPI\r
3247FakeExtractConfig (\r
3248 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
3249 IN CONST EFI_STRING Request,\r
3250 OUT EFI_STRING *Progress,\r
3251 OUT EFI_STRING *Results\r
3252 )\r
3253{\r
3254 if (Progress == NULL || Results == NULL) {\r
3255 return EFI_INVALID_PARAMETER;\r
3256 }\r
3257 *Progress = Request;\r
3258 return EFI_NOT_FOUND;\r
3259}\r
3260\r
3261/**\r
3262 This function processes the results of changes in configuration.\r
3263\r
3264\r
3265 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
3266 @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
3267 @param Progress A pointer to a string filled in with the offset of the most\r
3268 recent '&' before the first failing name/value pair (or the\r
3269 beginning of the string if the failure is in the first\r
3270 name/value pair) or the terminating NULL if all was successful.\r
3271\r
3272 @retval EFI_SUCCESS The Results is processed successfully.\r
3273 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
3274 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
3275\r
3276**/\r
3277EFI_STATUS\r
3278EFIAPI\r
3279FakeRouteConfig (\r
3280 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
3281 IN CONST EFI_STRING Configuration,\r
3282 OUT EFI_STRING *Progress\r
3283 )\r
3284{\r
3285 if (Configuration == NULL || Progress == NULL) {\r
3286 return EFI_INVALID_PARAMETER;\r
3287 }\r
3288\r
3289 return EFI_NOT_FOUND;\r
3290}\r
3291\r
3292\r
3293/**\r
3294 This function initialize the data mainly used in form browser.\r
3295\r
3296 @retval EFI_SUCCESS Initialize form data successfully.\r
3297 @retval Others Fail to Initialize form data.\r
3298\r
3299**/\r
3300EFI_STATUS\r
3301InitFormBrowser (\r
3302 VOID\r
3303 )\r
3304{\r
3305 EFI_STATUS Status;\r
3306 USER_MANAGER_CALLBACK_INFO *CallbackInfo;\r
3307 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
3308 EFI_HII_STRING_PROTOCOL *HiiString;\r
3309 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
3310\r
3311 //\r
3312 // Initialize driver private data.\r
3313 //\r
3314 CallbackInfo = AllocateZeroPool (sizeof (USER_MANAGER_CALLBACK_INFO));\r
3315 if (CallbackInfo == NULL) {\r
3316 return EFI_OUT_OF_RESOURCES;\r
3317 }\r
3318\r
3319 CallbackInfo->Signature = USER_MANAGER_SIGNATURE;\r
3320 CallbackInfo->ConfigAccess.ExtractConfig = FakeExtractConfig;\r
3321 CallbackInfo->ConfigAccess.RouteConfig = FakeRouteConfig;\r
3322 CallbackInfo->ConfigAccess.Callback = UserIdentifyManagerCallback;\r
3323\r
3324 //\r
3325 // Locate Hii Database protocol.\r
3326 //\r
3327 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);\r
3328 if (EFI_ERROR (Status)) {\r
3329 return Status;\r
3330 }\r
3331 CallbackInfo->HiiDatabase = HiiDatabase;\r
3332\r
3333 //\r
3334 // Locate HiiString protocol.\r
3335 //\r
3336 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
3337 if (EFI_ERROR (Status)) {\r
3338 return Status;\r
3339 }\r
3340 CallbackInfo->HiiString = HiiString;\r
3341\r
3342 //\r
3343 // Locate Formbrowser2 protocol.\r
3344 //\r
3345 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
3346 if (EFI_ERROR (Status)) {\r
3347 return Status;\r
3348 }\r
3349\r
3350 CallbackInfo->FormBrowser2 = FormBrowser2;\r
3351 CallbackInfo->DriverHandle = NULL;\r
3352 \r
3353 //\r
3354 // Install Device Path Protocol and Config Access protocol to driver handle.\r
3355 //\r
3356 Status = gBS->InstallMultipleProtocolInterfaces (\r
3357 &CallbackInfo->DriverHandle,\r
3358 &gEfiDevicePathProtocolGuid,\r
3359 &mHiiVendorDevicePath,\r
3360 &gEfiHiiConfigAccessProtocolGuid,\r
3361 &CallbackInfo->ConfigAccess,\r
3362 NULL\r
3363 );\r
3364 ASSERT_EFI_ERROR (Status);\r
3365\r
3366 //\r
3367 // Publish HII data.\r
3368 //\r
3369 CallbackInfo->HiiHandle = HiiAddPackages (\r
3370 &mUserManagerGuid,\r
3371 CallbackInfo->DriverHandle,\r
3372 UserIdentifyManagerStrings,\r
3373 UserIdentifyManagerVfrBin,\r
3374 NULL\r
3375 );\r
3376 if (CallbackInfo->HiiHandle == NULL) {\r
3377 return EFI_OUT_OF_RESOURCES;\r
3378 }\r
3379\r
3380 mCallbackInfo = CallbackInfo;\r
3381\r
3382 return EFI_SUCCESS;\r
3383}\r
3384\r
3385\r
3386/**\r
3387 Identify the user whose identification policy supports auto logon.\r
3388\r
3389 @param[in] ProviderIndex The provider index in the provider list.\r
3390 @param[out] User Points to user user profile if a user is identified successfully.\r
3391\r
3392 @retval EFI_SUCCESS Identify a user with the specified provider successfully.\r
3393 @retval Others Fail to identify a user.\r
3394\r
3395**/\r
3396EFI_STATUS\r
3397IdentifyAutoLogonUser (\r
3398 IN UINTN ProviderIndex,\r
3399 OUT USER_PROFILE_ENTRY **User\r
3400 )\r
3401{\r
3402 EFI_STATUS Status;\r
3403 EFI_USER_INFO *Info;\r
3404 UINT8 PolicyType;\r
3405\r
3406 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER));\r
3407 if (Info == NULL) {\r
3408 return EFI_OUT_OF_RESOURCES;\r
3409 }\r
3410\r
3411 Info->InfoType = EFI_USER_INFO_IDENTIFIER_RECORD;\r
3412 Info->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_IDENTIFIER);\r
3413\r
3414 //\r
3415 // Identify the specified credential provider's auto logon user.\r
3416 //\r
3417 Status = mProviderDb->Provider[ProviderIndex]->User (\r
3418 mProviderDb->Provider[ProviderIndex],\r
3419 NULL,\r
3420 (EFI_USER_INFO_IDENTIFIER *) (Info + 1)\r
3421 );\r
3422 if (EFI_ERROR (Status)) {\r
3423 FreePool (Info);\r
3424 return Status;\r
3425 }\r
3426 \r
3427 //\r
3428 // Find user with the specified user ID.\r
3429 //\r
3430 *User = NULL;\r
3431 Status = FindUserProfileByInfo (User, NULL, Info, Info->InfoSize);\r
3432 FreePool (Info);\r
3433 if (EFI_ERROR (Status)) {\r
3434 return Status;\r
3435 }\r
3436\r
3437 Status = GetIdentifyType ((EFI_USER_PROFILE_HANDLE) * User, &PolicyType);\r
3438 if (PolicyType == EFI_USER_INFO_IDENTITY_AND) {\r
3439 //\r
3440 // The identified user need also identified by other credential provider.\r
3441 // This can handle through select user.\r
3442 //\r
3443 return EFI_NOT_READY;\r
3444 }\r
3445 \r
3446 return Status;\r
3447}\r
3448\r
3449\r
3450/**\r
3451 Check whether the given console is ready.\r
3452\r
3453 @param[in] ProtocolGuid Points to the protocol guid of sonsole .\r
3454 \r
3455 @retval TRUE The given console is ready.\r
3456 @retval FALSE The given console is not ready.\r
3457 \r
3458**/\r
3459BOOLEAN\r
3460CheckConsole (\r
3461 EFI_GUID *ProtocolGuid \r
3462 )\r
3463{\r
3464 EFI_STATUS Status;\r
3465 UINTN HandleCount;\r
3466 EFI_HANDLE *HandleBuf;\r
3467 UINTN Index; \r
3468 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
3469 \r
3470 //\r
3471 // Try to find all the handle driver.\r
3472 //\r
3473 HandleCount = 0;\r
3474 HandleBuf = NULL;\r
3475 Status = gBS->LocateHandleBuffer (\r
3476 ByProtocol,\r
3477 ProtocolGuid,\r
3478 NULL,\r
3479 &HandleCount,\r
3480 &HandleBuf\r
3481 );\r
3482 if (EFI_ERROR (Status)) {\r
3483 return FALSE;\r
3484 }\r
3485\r
3486 for (Index = 0; Index < HandleCount; Index++) {\r
3487 DevicePath = DevicePathFromHandle (HandleBuf[Index]);\r
3488 if (DevicePath != NULL) {\r
3489 FreePool (HandleBuf);\r
3490 return TRUE;\r
3491 }\r
3492 }\r
3493 FreePool (HandleBuf); \r
3494 return FALSE;\r
3495}\r
3496\r
3497\r
3498/**\r
3499 Check whether the console is ready.\r
3500\r
3501 @retval TRUE The console is ready.\r
3502 @retval FALSE The console is not ready.\r
3503 \r
3504**/\r
3505BOOLEAN\r
3506IsConsoleReady (\r
3507 VOID\r
3508 )\r
3509{\r
3510 if (!CheckConsole (&gEfiSimpleTextOutProtocolGuid)) {\r
3511 return FALSE;\r
3512 }\r
3513\r
3514 if (!CheckConsole (&gEfiSimpleTextInProtocolGuid)) {\r
3515 if (!CheckConsole (&gEfiSimpleTextInputExProtocolGuid)) {\r
3516 return FALSE;\r
3517 }\r
3518 }\r
3519 \r
3520 return TRUE;\r
3521}\r
3522\r
3523\r
3524/**\r
3525 Identify a user to logon.\r
3526\r
3527 @param[out] User Points to user user profile if a user is identified successfully.\r
3528\r
3529 @retval EFI_SUCCESS Identify a user successfully.\r
3530\r
3531**/\r
3532EFI_STATUS\r
3533IdentifyUser (\r
3534 OUT USER_PROFILE_ENTRY **User\r
3535 )\r
3536{\r
3537 EFI_STATUS Status;\r
3538 UINTN Index;\r
3539 EFI_CREDENTIAL_LOGON_FLAGS AutoLogon;\r
3540 EFI_USER_INFO *IdentifyInfo;\r
3541 EFI_USER_INFO_IDENTITY_POLICY *Identity;\r
3542 EFI_USER_CREDENTIAL_PROTOCOL *UserCredential;\r
3543 USER_PROFILE_ENTRY *UserEntry;\r
3544\r
3545 //\r
3546 // Initialize credential providers.\r
3547 //\r
3548 InitProviderInfo ();\r
3549\r
3550 //\r
3551 // Initialize user profile database.\r
3552 //\r
3553 InitUserProfileDb ();\r
3554\r
3555 //\r
3556 // If only one user in system, and its identify policy is TRUE, then auto logon.\r
3557 //\r
3558 if (mUserProfileDb->UserProfileNum == 1) {\r
3559 UserEntry = (USER_PROFILE_ENTRY *) mUserProfileDb->UserProfile[0];\r
3560 IdentifyInfo = NULL;\r
3561 Status = FindUserInfoByType (UserEntry, &IdentifyInfo, EFI_USER_INFO_IDENTITY_POLICY_RECORD);\r
3562 if (EFI_ERROR (Status)) {\r
3563 return Status;\r
3564 }\r
3565 ASSERT (IdentifyInfo != NULL);\r
3566\r
3567 Identity = (EFI_USER_INFO_IDENTITY_POLICY *) ((UINT8 *) (IdentifyInfo + 1));\r
3568 if (Identity->Type == EFI_USER_INFO_IDENTITY_TRUE) {\r
3569 mCurrentUser = (EFI_USER_PROFILE_HANDLE) UserEntry;\r
3570 UpdateUserInfo (UserEntry);\r
3571 *User = UserEntry;\r
3572 return EFI_SUCCESS;\r
3573 }\r
3574 }\r
3575 \r
3576 //\r
3577 // Find and login the default & AutoLogon user.\r
3578 //\r
3579 for (Index = 0; Index < mProviderDb->Count; Index++) {\r
3580 UserCredential = mProviderDb->Provider[Index];\r
3581 Status = UserCredential->Default (UserCredential, &AutoLogon);\r
3582 if (EFI_ERROR (Status)) {\r
3583 continue;\r
3584 }\r
3585\r
3586 if ((AutoLogon & (EFI_CREDENTIAL_LOGON_FLAG_DEFAULT | EFI_CREDENTIAL_LOGON_FLAG_AUTO)) != 0) {\r
3587 Status = IdentifyAutoLogonUser (Index, &UserEntry);\r
3588 if (Status == EFI_SUCCESS) {\r
3589 mCurrentUser = (EFI_USER_PROFILE_HANDLE) UserEntry;\r
3590 UpdateUserInfo (UserEntry);\r
3591 *User = UserEntry;\r
3592 return EFI_SUCCESS;\r
3593 }\r
3594 }\r
3595 }\r
3596 \r
3597 if (!IsConsoleReady ()) {\r
3598 //\r
3599 // The console is still not ready for user selection.\r
3600 //\r
3601 return EFI_ACCESS_DENIED;\r
3602 }\r
3603\r
3604 //\r
3605 // Select a user and identify it.\r
3606 //\r
3607 mCallbackInfo->FormBrowser2->SendForm (\r
3608 mCallbackInfo->FormBrowser2,\r
3609 &mCallbackInfo->HiiHandle,\r
3610 1,\r
3611 &mUserManagerGuid,\r
3612 0,\r
3613 NULL,\r
3614 NULL\r
3615 );\r
3616 \r
3617 if (mIdentified) {\r
3618 *User = (USER_PROFILE_ENTRY *) mCurrentUser;\r
3619 UpdateUserInfo (*User);\r
3620 return EFI_SUCCESS;\r
3621 }\r
3622 \r
3623 return EFI_ACCESS_DENIED;\r
3624}\r
3625\r
3626\r
3627/**\r
3628 An empty function to pass error checking of CreateEventEx ().\r
3629 \r
3630 @param Event Event whose notification function is being invoked.\r
3631 @param Context Pointer to the notification function's context,\r
3632 which is implementation-dependent.\r
3633\r
3634**/\r
3635VOID\r
3636EFIAPI\r
3637InternalEmptyFuntion (\r
3638 IN EFI_EVENT Event,\r
3639 IN VOID *Context\r
3640 )\r
3641{\r
3642}\r
3643\r
3644\r
3645/**\r
3646 Create, Signal, and Close the User Profile Changed event.\r
3647\r
3648**/\r
3649VOID\r
3650SignalEventUserProfileChanged (\r
3651 VOID\r
3652 )\r
3653{\r
3654 EFI_STATUS Status;\r
3655 EFI_EVENT Event;\r
3656\r
3657 Status = gBS->CreateEventEx (\r
3658 EVT_NOTIFY_SIGNAL,\r
3659 TPL_CALLBACK,\r
3660 InternalEmptyFuntion,\r
3661 NULL,\r
3662 &gEfiEventUserProfileChangedGuid,\r
3663 &Event\r
3664 );\r
3665 ASSERT_EFI_ERROR (Status);\r
3666 gBS->SignalEvent (Event);\r
3667 gBS->CloseEvent (Event);\r
3668}\r
3669\r
3670\r
3671/**\r
3672 Create a new user profile.\r
3673\r
3674 This function creates a new user profile with only a new user identifier attached and returns \r
3675 its handle. The user profile is non-volatile, but the handle User can change across reboots.\r
3676\r
3677 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3678 @param[out] User On return, points to the new user profile handle. \r
3679 The user profile handle is unique only during this boot.\r
3680 \r
3681 @retval EFI_SUCCESS User profile was successfully created.\r
3682 @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to create a \r
3683 user profile.\r
3684 @retval EFI_UNSUPPORTED Creation of new user profiles is not supported.\r
3685 @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
3686 \r
3687**/\r
3688EFI_STATUS\r
3689EFIAPI\r
3690UserProfileCreate (\r
3691 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3692 OUT EFI_USER_PROFILE_HANDLE *User\r
3693 )\r
3694{\r
3695 EFI_STATUS Status;\r
3696\r
3697 if ((This == NULL) || (User == NULL)) {\r
3698 return EFI_INVALID_PARAMETER;\r
3699 }\r
3700\r
3701 //\r
3702 // Check the right of the current user.\r
3703 //\r
3704 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
3705 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS)) {\r
3706 return EFI_ACCESS_DENIED;\r
3707 }\r
3708 }\r
3709 \r
3710 //\r
3711 // Create new user profile\r
3712 //\r
3713 Status = CreateUserProfile ((USER_PROFILE_ENTRY **) User);\r
3714 if (EFI_ERROR (Status)) {\r
3715 return EFI_ACCESS_DENIED;\r
3716 }\r
3717 return EFI_SUCCESS;\r
3718}\r
3719\r
3720\r
3721/**\r
3722 Delete an existing user profile.\r
3723\r
3724 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3725 @param[in] User User profile handle. \r
3726\r
3727 @retval EFI_SUCCESS User profile was successfully deleted.\r
3728 @retval EFI_ACCESS_DENIED Current user does not have sufficient permissions to delete a user\r
3729 profile or there is only one user profile.\r
3730 @retval EFI_UNSUPPORTED Deletion of new user profiles is not supported.\r
3731 @retval EFI_INVALID_PARAMETER User does not refer to a valid user profile.\r
3732 \r
3733**/\r
3734EFI_STATUS\r
3735EFIAPI\r
3736UserProfileDelete (\r
3737 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3738 IN EFI_USER_PROFILE_HANDLE User\r
3739 )\r
3740{\r
3741 EFI_STATUS Status;\r
3742\r
3743 if (This == NULL) {\r
3744 return EFI_INVALID_PARAMETER;\r
3745 }\r
3746 \r
3747 //\r
3748 // Check the right of the current user.\r
3749 //\r
3750 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
3751 return EFI_ACCESS_DENIED;\r
3752 }\r
3753 \r
3754 //\r
3755 // Delete user profile.\r
3756 //\r
3757 Status = DelUserProfile (User);\r
3758 if (EFI_ERROR (Status)) {\r
3759 if (Status != EFI_INVALID_PARAMETER) {\r
3760 return EFI_ACCESS_DENIED;\r
3761 }\r
3762 return EFI_INVALID_PARAMETER;\r
3763 }\r
3764\r
3765 return EFI_SUCCESS;\r
3766}\r
3767\r
3768\r
3769/**\r
3770 Enumerate all of the enrolled users on the platform.\r
3771\r
3772 This function returns the next enrolled user profile. To retrieve the first user profile handle, \r
3773 point User at a NULL. Each subsequent call will retrieve another user profile handle until there \r
3774 are no more, at which point User will point to NULL. \r
3775\r
3776 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3777 @param[in, out] User On entry, points to the previous user profile handle or NULL to \r
3778 start enumeration. On exit, points to the next user profile handle\r
3779 or NULL if there are no more user profiles.\r
3780\r
3781 @retval EFI_SUCCESS Next enrolled user profile successfully returned. \r
3782 @retval EFI_ACCESS_DENIED Next enrolled user profile was not successfully returned.\r
3783 @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
3784**/\r
3785EFI_STATUS\r
3786EFIAPI\r
3787UserProfileGetNext (\r
3788 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3789 IN OUT EFI_USER_PROFILE_HANDLE *User\r
3790 )\r
3791{\r
3792 EFI_STATUS Status;\r
3793\r
3794 if ((This == NULL) || (User == NULL)) {\r
3795 return EFI_INVALID_PARAMETER;\r
3796 }\r
3797 \r
3798 Status = FindUserProfile ((USER_PROFILE_ENTRY **) User, TRUE, NULL);\r
3799 if (EFI_ERROR (Status)) {\r
3800 return EFI_ACCESS_DENIED;\r
3801 }\r
3802 return EFI_SUCCESS;\r
3803}\r
3804\r
3805\r
3806/**\r
3807 Return the current user profile handle.\r
3808\r
3809 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3810 @param[out] CurrentUser On return, points to the current user profile handle.\r
3811\r
3812 @retval EFI_SUCCESS Current user profile handle returned successfully. \r
3813 @retval EFI_INVALID_PARAMETER The CurrentUser parameter is NULL.\r
3814 \r
3815**/\r
3816EFI_STATUS\r
3817EFIAPI\r
3818UserProfileCurrent (\r
3819 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3820 OUT EFI_USER_PROFILE_HANDLE *CurrentUser\r
3821 )\r
3822{ \r
3823 //\r
3824 // Get current user profile.\r
3825 //\r
3826 if ((This == NULL) || (CurrentUser == NULL)) {\r
3827 return EFI_INVALID_PARAMETER;\r
3828 }\r
3829\r
3830 *CurrentUser = mCurrentUser;\r
3831 return EFI_SUCCESS;\r
3832}\r
3833\r
3834\r
3835/**\r
3836 Identify a user.\r
3837\r
3838 Identify the user and, if authenticated, returns the user handle and changes the current\r
3839 user profile. All user information marked as private in a previously selected profile\r
3840 is no longer available for inspection. \r
3841 Whenever the current user profile is changed then the an event with the GUID \r
3842 EFI_EVENT_GROUP_USER_PROFILE_CHANGED is signaled.\r
3843\r
3844 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3845 @param[out] User On return, points to the user profile handle for the current\r
3846 user profile.\r
3847\r
3848 @retval EFI_SUCCESS User was successfully identified.\r
3849 @retval EFI_ACCESS_DENIED User was not successfully identified.\r
3850 @retval EFI_INVALID_PARAMETER The User parameter is NULL.\r
3851 \r
3852**/\r
3853EFI_STATUS\r
3854EFIAPI\r
3855UserProfileIdentify (\r
3856 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3857 OUT EFI_USER_PROFILE_HANDLE *User\r
3858 )\r
3859{\r
3860 EFI_STATUS Status;\r
3861\r
3862 if ((This == NULL) || (User == NULL)) {\r
3863 return EFI_INVALID_PARAMETER;\r
3864 }\r
3865\r
3866 if (mCurrentUser != NULL) {\r
3867 *User = mCurrentUser;\r
3868 return EFI_SUCCESS;\r
3869 }\r
3870 \r
3871 //\r
3872 // Identify user\r
3873 //\r
3874 Status = IdentifyUser ((USER_PROFILE_ENTRY **) User);\r
3875 if (EFI_ERROR (Status)) {\r
3876 return EFI_ACCESS_DENIED;\r
3877 }\r
3878 \r
3879 //\r
3880 // Publish the user info into the EFI system configuration table.\r
3881 //\r
3882 PublishUserTable ();\r
3883\r
3884 //\r
3885 // Signal User Profile Changed event.\r
3886 //\r
3887 SignalEventUserProfileChanged ();\r
3888 return EFI_SUCCESS;\r
3889}\r
3890\r
3891/**\r
3892 Find a user using a user information record.\r
3893\r
3894 This function searches all user profiles for the specified user information record.\r
3895 The search starts with the user information record handle following UserInfo and \r
3896 continues until either the information is found or there are no more user profiles.\r
3897 A match occurs when the Info.InfoType field matches the user information record\r
3898 type and the user information record data matches the portion of Info.\r
3899\r
3900 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3901 @param[in, out] User On entry, points to the previously returned user profile \r
3902 handle, or NULL to start searching with the first user profile.\r
3903 On return, points to the user profile handle, or NULL if not\r
3904 found.\r
3905 @param[in, out] UserInfo On entry, points to the previously returned user information\r
3906 handle, or NULL to start searching with the first. On return, \r
3907 points to the user information handle of the user information\r
3908 record, or NULL if not found. Can be NULL, in which case only \r
3909 one user information record per user can be returned. \r
3910 @param[in] Info Points to the buffer containing the user information to be \r
3911 compared to the user information record. If the user information \r
3912 record data is empty, then only the user information record type \r
3913 is compared. If InfoSize is 0, then the user information record \r
3914 must be empty.\r
3915\r
3916 @param[in] InfoSize The size of Info, in bytes. \r
3917\r
3918 @retval EFI_SUCCESS User information was found. User points to the user profile\r
3919 handle, and UserInfo points to the user information handle.\r
3920 @retval EFI_NOT_FOUND User information was not found. User points to NULL, and \r
3921 UserInfo points to NULL.\r
3922 @retval EFI_INVALID_PARAMETER User is NULL. Or Info is NULL. \r
3923 \r
3924**/\r
3925EFI_STATUS\r
3926EFIAPI\r
3927UserProfileFind (\r
3928 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
3929 IN OUT EFI_USER_PROFILE_HANDLE *User,\r
3930 IN OUT EFI_USER_INFO_HANDLE *UserInfo OPTIONAL,\r
3931 IN CONST EFI_USER_INFO *Info,\r
3932 IN UINTN InfoSize\r
3933 )\r
3934{\r
3935 EFI_STATUS Status;\r
3936 UINTN Size;\r
3937\r
3938 if ((This == NULL) || (User == NULL) || (Info == NULL)) {\r
3939 return EFI_INVALID_PARAMETER;\r
3940 }\r
3941\r
3942 if (InfoSize == 0) {\r
3943 //\r
3944 // If InfoSize is 0, then the user information record must be empty.\r
3945 //\r
3946 if (Info->InfoSize != sizeof (EFI_USER_INFO)) {\r
3947 return EFI_INVALID_PARAMETER;\r
3948 }\r
3949 } else {\r
3950 if (InfoSize != Info->InfoSize) {\r
3951 return EFI_INVALID_PARAMETER;\r
3952 }\r
3953 }\r
3954 Size = Info->InfoSize; \r
3955 \r
3956 //\r
3957 // Find user profile accdoring to user information.\r
3958 //\r
3959 Status = FindUserProfileByInfo (\r
3960 (USER_PROFILE_ENTRY **) User,\r
3961 (EFI_USER_INFO **) UserInfo,\r
3962 (EFI_USER_INFO *) Info,\r
3963 Size\r
3964 );\r
3965 if (EFI_ERROR (Status)) {\r
3966 *User = NULL;\r
3967 if (UserInfo != NULL) {\r
3968 *UserInfo = NULL;\r
3969 }\r
3970 return EFI_NOT_FOUND;\r
3971 }\r
3972 \r
3973 return EFI_SUCCESS;\r
3974}\r
3975\r
3976\r
3977/**\r
3978 Return information attached to the user.\r
3979\r
3980 This function returns user information. The format of the information is described in User \r
3981 Information. The function may return EFI_ACCESS_DENIED if the information is marked private \r
3982 and the handle specified by User is not the current user profile. The function may return \r
3983 EFI_ACCESS_DENIED if the information is marked protected and the information is associated \r
3984 with a credential provider for which the user has not been authenticated.\r
3985\r
3986 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
3987 @param[in] User Handle of the user whose profile will be retrieved. \r
3988 @param[in] UserInfo Handle of the user information data record. \r
3989 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes. On exit, \r
3990 holds the user information. If the buffer is too small to hold the \r
3991 information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is \r
3992 updated to contain the number of bytes actually required. \r
3993 @param[in, out] InfoSize On entry, points to the size of Info. On return, points to the size \r
3994 of the user information. \r
3995\r
3996 @retval EFI_SUCCESS Information returned successfully.\r
3997 @retval EFI_ACCESS_DENIED The information about the specified user cannot be accessed by the \r
3998 current user.\r
3999 @retval EFI_BUFFER_TOO_SMALL The number of bytes specified by *InfoSize is too small to hold the \r
4000 returned data. The actual size required is returned in *InfoSize.\r
4001 @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not refer \r
4002 to a valid user info handle.\r
4003 @retval EFI_INVALID_PARAMETER Info is NULL or InfoSize is NULL.\r
4004 \r
4005**/\r
4006EFI_STATUS\r
4007EFIAPI\r
4008UserProfileGetInfo (\r
4009 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
4010 IN EFI_USER_PROFILE_HANDLE User,\r
4011 IN EFI_USER_INFO_HANDLE UserInfo,\r
4012 OUT EFI_USER_INFO *Info,\r
4013 IN OUT UINTN *InfoSize\r
4014 )\r
4015{\r
4016 EFI_STATUS Status;\r
4017\r
4018 if ((This == NULL) || (InfoSize == NULL)) {\r
4019 return EFI_INVALID_PARAMETER;\r
4020 }\r
4021\r
4022 if ((*InfoSize != 0) && (Info == NULL)) {\r
4023 return EFI_INVALID_PARAMETER;\r
4024 }\r
4025 \r
4026 if ((User == NULL) || (UserInfo == NULL)) {\r
4027 return EFI_NOT_FOUND;\r
4028 }\r
4029 \r
4030 Status = GetUserInfo (User, UserInfo, Info, InfoSize, TRUE);\r
4031 if (EFI_ERROR (Status)) {\r
4032 if (Status == EFI_BUFFER_TOO_SMALL) {\r
4033 return EFI_BUFFER_TOO_SMALL;\r
4034 }\r
4035 return EFI_ACCESS_DENIED;\r
4036 }\r
4037 return EFI_SUCCESS;\r
4038}\r
4039\r
4040\r
4041/**\r
4042 Add or update user information.\r
4043\r
4044 This function changes user information. If NULL is pointed to by UserInfo, then a new user \r
4045 information record is created and its handle is returned in UserInfo. Otherwise, the existing \r
4046 one is replaced.\r
4047 If EFI_USER_INFO_EXCLUSIVE is specified in Info and a user information record of the same \r
4048 type already exists in the user profile, then EFI_ACCESS_DENIED will be returned and UserInfo\r
4049 will point to the handle of the existing record.\r
4050\r
4051 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
4052 @param[in] User Handle of the user whose profile will be retrieved. \r
4053 @param[in, out] UserInfo Handle of the user information data record. \r
4054 @param[in] Info On entry, points to a buffer of at least *InfoSize bytes. On exit, \r
4055 holds the user information. If the buffer is too small to hold the \r
4056 information, then EFI_BUFFER_TOO_SMALL is returned and InfoSize is \r
4057 updated to contain the number of bytes actually required. \r
4058 @param[in] InfoSize On entry, points to the size of Info. On return, points to the size \r
4059 of the user information. \r
4060\r
4061 @retval EFI_SUCCESS Information returned successfully.\r
4062 @retval EFI_ACCESS_DENIED The record is exclusive.\r
4063 @retval EFI_SECURITY_VIOLATION The current user does not have permission to change the specified \r
4064 user profile or user information record.\r
4065 @retval EFI_NOT_FOUND User does not refer to a valid user profile or UserInfo does not \r
4066 refer to a valid user info handle.\r
4067 @retval EFI_INVALID_PARAMETER UserInfo is NULL or Info is NULL. \r
4068**/\r
4069EFI_STATUS\r
4070EFIAPI\r
4071UserProfileSetInfo (\r
4072 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
4073 IN EFI_USER_PROFILE_HANDLE User,\r
4074 IN OUT EFI_USER_INFO_HANDLE *UserInfo,\r
4075 IN CONST EFI_USER_INFO *Info,\r
4076 IN UINTN InfoSize\r
4077 )\r
4078{\r
4079 EFI_STATUS Status;\r
4080\r
4081 if ((This == NULL) || (User == NULL) || (UserInfo == NULL) || (Info == NULL)) {\r
4082 return EFI_INVALID_PARAMETER;\r
4083 }\r
4084 \r
4085 //\r
4086 // Check the right of the current user.\r
4087 //\r
4088 if (User != mCurrentUser) {\r
4089 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
4090 if (*UserInfo != NULL) {\r
4091 //\r
4092 // Can't update info in other profiles without MANAGE right.\r
4093 //\r
4094 return EFI_SECURITY_VIOLATION;\r
4095 }\r
4096 \r
4097 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_OTHERS)) {\r
4098 //\r
4099 // Can't add info into other profiles.\r
4100 //\r
4101 return EFI_SECURITY_VIOLATION;\r
4102 }\r
4103 }\r
4104 }\r
4105\r
4106 if (User == mCurrentUser) {\r
4107 if (CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_ENROLL_SELF)) {\r
4108 //\r
4109 // Only identify policy can be added/updated.\r
4110 //\r
4111 if (Info->InfoType != EFI_USER_INFO_IDENTITY_POLICY_RECORD) {\r
4112 return EFI_SECURITY_VIOLATION;\r
4113 }\r
4114 }\r
4115 }\r
4116 \r
4117 //\r
4118 // Modify user information.\r
4119 //\r
4120 Status = ModifyUserInfo (User, (EFI_USER_INFO **) UserInfo, Info, InfoSize);\r
4121 if (EFI_ERROR (Status)) {\r
4122 if (Status == EFI_ACCESS_DENIED) {\r
4123 return EFI_ACCESS_DENIED; \r
4124 }\r
4125 return EFI_SECURITY_VIOLATION;\r
4126 }\r
4127 return EFI_SUCCESS;\r
4128}\r
4129\r
4130\r
4131/**\r
4132 Called by credential provider to notify of information change.\r
4133\r
4134 This function allows the credential provider to notify the User Identity Manager when user status \r
4135 has changed while deselected.\r
4136 If the User Identity Manager doesn't support asynchronous changes in credentials, then this function \r
4137 should return EFI_UNSUPPORTED. \r
4138 If the User Identity Manager supports this, it will call User() to get the user identifier and then \r
4139 GetNextInfo() and GetInfo() in the User Credential Protocol to get all of the information from the \r
4140 credential and add it.\r
4141\r
4142 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
4143 @param[in] Changed Handle on which is installed an instance of the EFI_USER_CREDENTIAL_PROTOCOL \r
4144 where the user has changed.\r
4145\r
4146 @retval EFI_SUCCESS The User Identity Manager has handled the notification.\r
4147 @retval EFI_NOT_READY The function was called while the specified credential provider was not selected.\r
4148 @retval EFI_UNSUPPORTED The User Identity Manager doesn't support asynchronous notifications.\r
4149 \r
4150**/\r
4151EFI_STATUS\r
4152EFIAPI\r
4153UserProfileNotify (\r
4154 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
4155 IN EFI_HANDLE Changed\r
4156 )\r
4157{\r
4158 EFI_STATUS Status;\r
4159 EFI_USER_CREDENTIAL_PROTOCOL *Provider;\r
4160 EFI_USER_INFO_IDENTIFIER UserId;\r
4161 EFI_USER_INFO_HANDLE UserInfo;\r
4162 EFI_USER_INFO_HANDLE UserInfo2;\r
4163 UINTN InfoSize;\r
4164 EFI_USER_INFO *Info;\r
4165 USER_PROFILE_ENTRY *User;\r
4166\r
4167 if (This == NULL) {\r
4168 return EFI_INVALID_PARAMETER;\r
4169 }\r
4170 \r
4171 Status = gBS->HandleProtocol (\r
4172 Changed,\r
4173 &gEfiUserCredentialProtocolGuid,\r
4174 (VOID **) &Provider\r
4175 );\r
4176 if (EFI_ERROR (Status)) {\r
4177 return Status;\r
4178 }\r
4179\r
4180 Status = Provider->User (Provider, NULL, &UserId);\r
4181 if (EFI_ERROR (Status)) {\r
4182 return EFI_NOT_READY;\r
4183 }\r
4184\r
4185 //\r
4186 // Find user with the UserId.\r
4187 //\r
4188 User = NULL;\r
4189 while (TRUE) {\r
4190 //\r
4191 // Find next user profile.\r
4192 // \r
4193 Status = FindUserProfile (&User, TRUE, NULL);\r
4194 if (EFI_ERROR (Status)) {\r
4195 return Status;\r
4196 }\r
4197 \r
4198 //\r
4199 // Find the user information.\r
4200 //\r
4201 Info = NULL;\r
4202 FindUserInfoByType (User, &Info, EFI_USER_INFO_IDENTIFIER_RECORD);\r
4203 if (CompareMem ((UINT8 *) (Info + 1), UserId, sizeof (UserId)) == 0) {\r
4204 //\r
4205 // Found the infomation record. \r
4206 //\r
4207 break;\r
4208 }\r
4209 }\r
4210\r
4211 UserInfo = NULL;\r
4212 do {\r
4213 //\r
4214 // Get user info handle.\r
4215 //\r
4216 Status = Provider->GetNextInfo(Provider, &UserInfo);\r
4217 if (EFI_ERROR (Status)) {\r
4218 return EFI_SUCCESS;\r
4219 }\r
4220\r
4221 //\r
4222 // Get the user information from the user info handle.\r
4223 // \r
4224 InfoSize = 0;\r
4225 Status = Provider->GetInfo(Provider, UserInfo, NULL, &InfoSize);\r
4226 if (EFI_ERROR (Status)) {\r
4227 if (Status == EFI_BUFFER_TOO_SMALL) {\r
4228 Info = AllocateZeroPool (InfoSize);\r
4229 if (Info == NULL) {\r
4230 return EFI_OUT_OF_RESOURCES;\r
4231 }\r
4232 Status = Provider->GetInfo(Provider, UserInfo, Info, &InfoSize);\r
4233 if (EFI_ERROR (Status)) {\r
4234 FreePool (Info);\r
4235 break;\r
4236 }\r
4237 }\r
4238 break;\r
4239 }\r
4240\r
4241 //\r
4242 // Save the user information.\r
4243 // \r
4244 UserInfo2 = NULL;\r
4245 Status = UserProfileSetInfo (&gUserIdentifyManager, (EFI_USER_PROFILE_HANDLE)User, &UserInfo2, Info, InfoSize);\r
4246 FreePool (Info);\r
4247 if (EFI_ERROR (Status)) {\r
4248 break;\r
4249 }\r
4250 } while (TRUE);\r
4251 \r
4252 return Status;\r
4253}\r
4254\r
4255\r
4256/**\r
4257 Delete user information.\r
4258\r
4259 Delete the user information attached to the user profile specified by the UserInfo.\r
4260\r
4261 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
4262 @param[in] User Handle of the user whose information will be deleted.\r
4263 @param[in] UserInfo Handle of the user information to remove.\r
4264\r
4265 @retval EFI_SUCCESS User information deleted successfully.\r
4266 @retval EFI_NOT_FOUND User information record UserInfo does not exist in the user profile.\r
4267 @retval EFI_ACCESS_DENIED The current user does not have permission to delete this user information. \r
4268 \r
4269**/\r
4270EFI_STATUS\r
4271EFIAPI\r
4272UserProfileDeleteInfo (\r
4273 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
4274 IN EFI_USER_PROFILE_HANDLE User,\r
4275 IN EFI_USER_INFO_HANDLE UserInfo\r
4276 )\r
4277{\r
4278 EFI_STATUS Status;\r
4279\r
4280 if (This == NULL) {\r
4281 return EFI_INVALID_PARAMETER;\r
4282 }\r
4283 \r
4284 //\r
4285 // Check the right of the current user.\r
4286 //\r
4287 if (User != mCurrentUser) {\r
4288 if (!CheckCurrentUserAccessRight (EFI_USER_INFO_ACCESS_MANAGE)) {\r
4289 return EFI_ACCESS_DENIED;\r
4290 }\r
4291 }\r
4292 \r
4293 //\r
4294 // Delete user information.\r
4295 //\r
4296 Status = DelUserInfo (User, UserInfo, TRUE);\r
4297 if (EFI_ERROR (Status)) {\r
4298 if (Status == EFI_NOT_FOUND) {\r
4299 return EFI_NOT_FOUND;\r
4300 }\r
4301 return EFI_ACCESS_DENIED;\r
4302 } \r
4303 return EFI_SUCCESS;\r
4304}\r
4305\r
4306\r
4307/**\r
4308 Enumerate user information of all the enrolled users on the platform.\r
4309\r
4310 This function returns the next user information record. To retrieve the first user \r
4311 information record handle, point UserInfo at a NULL. Each subsequent call will retrieve \r
4312 another user information record handle until there are no more, at which point UserInfo \r
4313 will point to NULL. \r
4314\r
4315 @param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.\r
4316 @param[in] User Handle of the user whose information will be deleted.\r
4317 @param[in, out] UserInfo Handle of the user information to remove.\r
4318\r
4319 @retval EFI_SUCCESS User information returned.\r
4320 @retval EFI_NOT_FOUND No more user information found.\r
4321 @retval EFI_INVALID_PARAMETER UserInfo is NULL.\r
4322 \r
4323**/\r
4324EFI_STATUS\r
4325EFIAPI\r
4326UserProfileGetNextInfo (\r
4327 IN CONST EFI_USER_MANAGER_PROTOCOL *This,\r
4328 IN EFI_USER_PROFILE_HANDLE User,\r
4329 IN OUT EFI_USER_INFO_HANDLE *UserInfo\r
4330 )\r
4331{\r
4332 if ((This == NULL) || (UserInfo == NULL)) {\r
4333 return EFI_INVALID_PARAMETER;\r
4334 }\r
4335 //\r
4336 // Get next user information entry.\r
4337 //\r
4338 return FindUserInfo (User, (EFI_USER_INFO **) UserInfo, TRUE, NULL);\r
4339}\r
4340\r
4341\r
4342/**\r
4343 Main entry for this driver.\r
4344\r
4345 @param[in] ImageHandle Image handle this driver.\r
4346 @param[in] SystemTable Pointer to SystemTable.\r
4347\r
4348 @retval EFI_SUCESS This function always complete successfully.\r
4349\r
4350**/\r
4351EFI_STATUS\r
4352EFIAPI\r
4353UserIdentifyManagerInit (\r
4354 IN EFI_HANDLE ImageHandle,\r
4355 IN EFI_SYSTEM_TABLE *SystemTable\r
4356 )\r
4357{\r
4358\r
4359 EFI_STATUS Status;\r
4360\r
4361 //\r
4362 // Initiate form browser.\r
4363 //\r
4364 InitFormBrowser ();\r
4365\r
4366 //\r
4367 // Install protocol interfaces for the User Identity Manager.\r
4368 //\r
4369 Status = gBS->InstallProtocolInterface (\r
4370 &mCallbackInfo->DriverHandle,\r
4371 &gEfiUserManagerProtocolGuid,\r
4372 EFI_NATIVE_INTERFACE,\r
4373 &gUserIdentifyManager\r
4374 );\r
4375 ASSERT_EFI_ERROR (Status); \r
4376\r
4377 LoadDeferredImageInit (ImageHandle);\r
4378 return EFI_SUCCESS;\r
4379}\r
4380\r
4381\r