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