1 /** @file 2 The functions for access policy modification. 3 4 Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include "UserProfileManager.h" 16 17 /** 18 Collect all the access policy data to mUserInfo.AccessPolicy, 19 and save it to user profile. 20 21 **/ 22 VOID 23 SaveAccessPolicy ( 24 VOID 25 ) 26 { 27 EFI_STATUS Status; 28 UINTN OffSet; 29 UINTN Size; 30 EFI_USER_INFO_ACCESS_CONTROL Control; 31 EFI_USER_INFO_HANDLE UserInfo; 32 EFI_USER_INFO *Info; 33 34 if (mUserInfo.AccessPolicy != NULL) { 35 FreePool (mUserInfo.AccessPolicy); 36 } 37 mUserInfo.AccessPolicy = NULL; 38 mUserInfo.AccessPolicyLen = 0; 39 mUserInfo.AccessPolicyModified = TRUE; 40 OffSet = 0; 41 42 // 43 // Save access right. 44 // 45 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL); 46 if (mUserInfo.AccessPolicyLen - OffSet < Size) { 47 ExpandMemory (OffSet, Size); 48 } 49 50 Control.Type = mAccessInfo.AccessRight; 51 Control.Size = (UINT32) Size; 52 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control)); 53 OffSet += sizeof (Control); 54 55 // 56 // Save access setup. 57 // 58 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (EFI_GUID); 59 if (mUserInfo.AccessPolicyLen - OffSet < Size) { 60 ExpandMemory (OffSet, Size); 61 } 62 63 Control.Type = EFI_USER_INFO_ACCESS_SETUP; 64 Control.Size = (UINT32) Size; 65 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control)); 66 OffSet += sizeof (Control); 67 68 if (mAccessInfo.AccessSetup == ACCESS_SETUP_NORMAL) { 69 CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupNormalGuid); 70 } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_RESTRICTED) { 71 CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupRestrictedGuid); 72 } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_ADMIN) { 73 CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupAdminGuid); 74 } 75 OffSet += sizeof (EFI_GUID); 76 77 // 78 // Save access of boot order. 79 // 80 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (UINT32); 81 if (mUserInfo.AccessPolicyLen - OffSet < Size) { 82 ExpandMemory (OffSet, Size); 83 } 84 85 Control.Type = EFI_USER_INFO_ACCESS_BOOT_ORDER; 86 Control.Size = (UINT32) Size; 87 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control)); 88 OffSet += sizeof (Control); 89 90 CopyMem ((UINT8 *) (mUserInfo.AccessPolicy + OffSet), &mAccessInfo.AccessBootOrder, sizeof (UINT32)); 91 OffSet += sizeof (UINT32); 92 93 // 94 // Save permit load. 95 // 96 if (mAccessInfo.LoadPermitLen > 0) { 97 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadPermitLen; 98 if (mUserInfo.AccessPolicyLen - OffSet < Size) { 99 ExpandMemory (OffSet, Size); 100 } 101 102 Control.Type = EFI_USER_INFO_ACCESS_PERMIT_LOAD; 103 Control.Size = (UINT32) Size; 104 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control)); 105 OffSet += sizeof (Control); 106 107 CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadPermit, mAccessInfo.LoadPermitLen); 108 OffSet += mAccessInfo.LoadPermitLen; 109 } 110 111 // 112 // Save forbid load. 113 // 114 if (mAccessInfo.LoadForbidLen > 0) { 115 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadForbidLen; 116 if (mUserInfo.AccessPolicyLen - OffSet < Size) { 117 ExpandMemory (OffSet, Size); 118 } 119 120 Control.Type = EFI_USER_INFO_ACCESS_FORBID_LOAD; 121 Control.Size = (UINT32) Size; 122 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control)); 123 OffSet += sizeof (Control); 124 125 CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen); 126 OffSet += mAccessInfo.LoadForbidLen; 127 } 128 129 // 130 // Save permit connect. 131 // 132 if (mAccessInfo.ConnectPermitLen > 0) { 133 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectPermitLen; 134 if (mUserInfo.AccessPolicyLen - OffSet < Size) { 135 ExpandMemory (OffSet, Size); 136 } 137 138 Control.Type = EFI_USER_INFO_ACCESS_PERMIT_CONNECT; 139 Control.Size = (UINT32) Size; 140 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control)); 141 OffSet += sizeof (Control); 142 143 CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectPermit, mAccessInfo.ConnectPermitLen); 144 OffSet += mAccessInfo.ConnectPermitLen; 145 } 146 147 // 148 // Save forbid connect. 149 // 150 if (mAccessInfo.ConnectForbidLen > 0) { 151 Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectForbidLen; 152 if (mUserInfo.AccessPolicyLen - OffSet < Size) { 153 ExpandMemory (OffSet, Size); 154 } 155 156 Control.Type = EFI_USER_INFO_ACCESS_FORBID_CONNECT; 157 Control.Size = (UINT32) Size; 158 CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control)); 159 OffSet += sizeof (Control); 160 161 CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectForbid, mAccessInfo.ConnectForbidLen); 162 OffSet += mAccessInfo.ConnectForbidLen; 163 } 164 165 mUserInfo.AccessPolicyLen = OffSet; 166 167 // 168 // Save access policy. 169 // 170 if (mUserInfo.AccessPolicyModified && (mUserInfo.AccessPolicyLen > 0) && (mUserInfo.AccessPolicy != NULL)) { 171 Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen); 172 if (Info == NULL) { 173 return ; 174 } 175 176 Status = FindInfoByType (mModifyUser, EFI_USER_INFO_ACCESS_POLICY_RECORD, &UserInfo); 177 if (!EFI_ERROR (Status)) { 178 Info->InfoType = EFI_USER_INFO_ACCESS_POLICY_RECORD; 179 Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | 180 EFI_USER_INFO_PUBLIC | 181 EFI_USER_INFO_EXCLUSIVE; 182 Info->InfoSize = (UINT32) (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen); 183 CopyMem ((UINT8 *) (Info + 1), mUserInfo.AccessPolicy, mUserInfo.AccessPolicyLen); 184 Status = mUserManager->SetInfo ( 185 mUserManager, 186 mModifyUser, 187 &UserInfo, 188 Info, 189 Info->InfoSize 190 ); 191 mUserInfo.AccessPolicyModified = FALSE; 192 } 193 FreePool (Info); 194 } 195 196 if (mAccessInfo.ConnectForbid != NULL) { 197 FreePool (mAccessInfo.ConnectForbid); 198 mAccessInfo.ConnectForbid = NULL; 199 } 200 201 if (mAccessInfo.ConnectPermit != NULL) { 202 FreePool (mAccessInfo.ConnectPermit); 203 mAccessInfo.ConnectPermit = NULL; 204 } 205 206 if (mAccessInfo.LoadForbid != NULL) { 207 FreePool (mAccessInfo.LoadForbid); 208 mAccessInfo.LoadForbid = NULL; 209 } 210 211 if (mAccessInfo.LoadPermit != NULL) { 212 FreePool (mAccessInfo.LoadPermit); 213 mAccessInfo.LoadPermit = NULL; 214 } 215 } 216 217 /** 218 Create an action OpCode with QuestionID and DevicePath on a given OpCodeHandle. 219 220 @param[in] QuestionID The question ID. 221 @param[in] DevicePath Points to device path. 222 @param[in] OpCodeHandle Points to container for dynamic created opcodes. 223 224 **/ 225 VOID 226 AddDevicePath ( 227 IN UINTN QuestionID, 228 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, 229 IN VOID *OpCodeHandle 230 ) 231 { 232 EFI_DEVICE_PATH_PROTOCOL *Next; 233 EFI_STRING_ID NameID; 234 EFI_STRING DriverName; 235 236 // 237 // Get driver file name node. 238 // 239 Next = DevicePath; 240 while (!IsDevicePathEnd (Next)) { 241 DevicePath = Next; 242 Next = NextDevicePathNode (Next); 243 } 244 245 // 246 // Display the device path in form. 247 // 248 DriverName = ConvertDevicePathToText (DevicePath, FALSE, FALSE); 249 NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL); 250 FreePool (DriverName); 251 if (NameID == 0) { 252 return ; 253 } 254 255 HiiCreateActionOpCode ( 256 OpCodeHandle, // Container for dynamic created opcodes 257 (UINT16) QuestionID, // Question ID 258 NameID, // Prompt text 259 STRING_TOKEN (STR_NULL_STRING), // Help text 260 EFI_IFR_FLAG_CALLBACK, // Question flag 261 0 // Action String ID 262 ); 263 } 264 265 266 /** 267 Check whether the DevicePath is in the device path forbid list 268 (mAccessInfo.LoadForbid). 269 270 @param[in] DevicePath Points to device path. 271 272 @retval TRUE The DevicePath is in the device path forbid list. 273 @retval FALSE The DevicePath is not in the device path forbid list. 274 275 **/ 276 BOOLEAN 277 IsLoadForbidden ( 278 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 279 ) 280 { 281 UINTN OffSet; 282 UINTN DPSize; 283 UINTN Size; 284 EFI_DEVICE_PATH_PROTOCOL *Dp; 285 286 OffSet = 0; 287 Size = GetDevicePathSize (DevicePath); 288 // 289 // Check each device path. 290 // 291 while (OffSet < mAccessInfo.LoadForbidLen) { 292 Dp = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet); 293 DPSize = GetDevicePathSize (Dp); 294 // 295 // Compare device path. 296 // 297 if ((DPSize == Size) && (CompareMem (DevicePath, Dp, Size) == 0)) { 298 return TRUE; 299 } 300 OffSet += DPSize; 301 } 302 return FALSE; 303 } 304 305 306 /** 307 Display the permit load device path in the loadable device path list. 308 309 **/ 310 VOID 311 DisplayLoadPermit( 312 VOID 313 ) 314 { 315 EFI_STATUS Status; 316 CHAR16 *Order; 317 UINTN OrderSize; 318 UINTN ListCount; 319 UINTN Index; 320 UINT8 *Var; 321 UINT8 *VarPtr; 322 CHAR16 VarName[12]; 323 VOID *StartOpCodeHandle; 324 VOID *EndOpCodeHandle; 325 EFI_IFR_GUID_LABEL *StartLabel; 326 EFI_IFR_GUID_LABEL *EndLabel; 327 328 // 329 // Get DriverOrder. 330 // 331 OrderSize = 0; 332 Status = gRT->GetVariable ( 333 L"DriverOrder", 334 &gEfiGlobalVariableGuid, 335 NULL, 336 &OrderSize, 337 NULL 338 ); 339 if (Status != EFI_BUFFER_TOO_SMALL) { 340 return ; 341 } 342 343 Order = AllocateZeroPool (OrderSize); 344 if (Order == NULL) { 345 return ; 346 } 347 348 Status = gRT->GetVariable ( 349 L"DriverOrder", 350 &gEfiGlobalVariableGuid, 351 NULL, 352 &OrderSize, 353 Order 354 ); 355 if (EFI_ERROR (Status)) { 356 return ; 357 } 358 359 // 360 // Initialize the container for dynamic opcodes. 361 // 362 StartOpCodeHandle = HiiAllocateOpCodeHandle (); 363 ASSERT (StartOpCodeHandle != NULL); 364 365 EndOpCodeHandle = HiiAllocateOpCodeHandle (); 366 ASSERT (EndOpCodeHandle != NULL); 367 368 // 369 // Create Hii Extend Label OpCode. 370 // 371 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( 372 StartOpCodeHandle, 373 &gEfiIfrTianoGuid, 374 NULL, 375 sizeof (EFI_IFR_GUID_LABEL) 376 ); 377 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 378 StartLabel->Number = LABEL_PERMIT_LOAD_FUNC; 379 380 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( 381 EndOpCodeHandle, 382 &gEfiIfrTianoGuid, 383 NULL, 384 sizeof (EFI_IFR_GUID_LABEL) 385 ); 386 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 387 EndLabel->Number = LABEL_END; 388 389 // 390 // Add each driver option. 391 // 392 Var = NULL; 393 ListCount = OrderSize / sizeof (UINT16); 394 for (Index = 0; Index < ListCount; Index++) { 395 // 396 // Get driver device path. 397 // 398 UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", Order[Index]); 399 GetEfiGlobalVariable2 (VarName, (VOID**)&Var, NULL); 400 if (Var == NULL) { 401 continue; 402 } 403 404 // 405 // Check whether the driver is already forbidden. 406 // 407 408 VarPtr = Var; 409 // 410 // Skip attribute. 411 // 412 VarPtr += sizeof (UINT32); 413 414 // 415 // Skip device path lenth. 416 // 417 VarPtr += sizeof (UINT16); 418 419 // 420 // Skip descript string. 421 // 422 VarPtr += StrSize ((UINT16 *) VarPtr); 423 424 if (IsLoadForbidden ((EFI_DEVICE_PATH_PROTOCOL *) VarPtr)) { 425 FreePool (Var); 426 Var = NULL; 427 continue; 428 } 429 430 AddDevicePath ( 431 KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_PERMIT_MODIFY | Order[Index], 432 (EFI_DEVICE_PATH_PROTOCOL *) VarPtr, 433 StartOpCodeHandle 434 ); 435 FreePool (Var); 436 Var = NULL; 437 } 438 439 HiiUpdateForm ( 440 mCallbackInfo->HiiHandle, // HII handle 441 &gUserProfileManagerGuid, // Formset GUID 442 FORMID_PERMIT_LOAD_DP, // Form ID 443 StartOpCodeHandle, // Label for where to insert opcodes 444 EndOpCodeHandle // Replace data 445 ); 446 447 HiiFreeOpCodeHandle (StartOpCodeHandle); 448 HiiFreeOpCodeHandle (EndOpCodeHandle); 449 450 // 451 // Clear Environment. 452 // 453 if (Var != NULL) { 454 FreePool (Var); 455 } 456 FreePool (Order); 457 } 458 459 460 /** 461 Display the forbid load device path list (mAccessInfo.LoadForbid). 462 463 **/ 464 VOID 465 DisplayLoadForbid ( 466 VOID 467 ) 468 { 469 UINTN Offset; 470 UINTN DPSize; 471 UINTN Index; 472 EFI_DEVICE_PATH_PROTOCOL *Dp; 473 VOID *StartOpCodeHandle; 474 VOID *EndOpCodeHandle; 475 EFI_IFR_GUID_LABEL *StartLabel; 476 EFI_IFR_GUID_LABEL *EndLabel; 477 478 // 479 // Initialize the container for dynamic opcodes. 480 // 481 StartOpCodeHandle = HiiAllocateOpCodeHandle (); 482 ASSERT (StartOpCodeHandle != NULL); 483 484 EndOpCodeHandle = HiiAllocateOpCodeHandle (); 485 ASSERT (EndOpCodeHandle != NULL); 486 487 // 488 // Create Hii Extend Label OpCode. 489 // 490 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( 491 StartOpCodeHandle, 492 &gEfiIfrTianoGuid, 493 NULL, 494 sizeof (EFI_IFR_GUID_LABEL) 495 ); 496 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 497 StartLabel->Number = LABLE_FORBID_LOAD_FUNC; 498 499 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( 500 EndOpCodeHandle, 501 &gEfiIfrTianoGuid, 502 NULL, 503 sizeof (EFI_IFR_GUID_LABEL) 504 ); 505 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 506 EndLabel->Number = LABEL_END; 507 508 // 509 // Add each forbid load drivers. 510 // 511 Offset = 0; 512 Index = 0; 513 while (Offset < mAccessInfo.LoadForbidLen) { 514 Dp = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + Offset); 515 DPSize = GetDevicePathSize (Dp); 516 AddDevicePath ( 517 KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_FORBID_MODIFY | Index, 518 Dp, 519 StartOpCodeHandle 520 ); 521 Index++; 522 Offset += DPSize; 523 } 524 525 HiiUpdateForm ( 526 mCallbackInfo->HiiHandle, // HII handle 527 &gUserProfileManagerGuid, // Formset GUID 528 FORMID_FORBID_LOAD_DP, // Form ID 529 StartOpCodeHandle, // Label for where to insert opcodes 530 EndOpCodeHandle // Replace data 531 ); 532 533 HiiFreeOpCodeHandle (StartOpCodeHandle); 534 HiiFreeOpCodeHandle (EndOpCodeHandle); 535 } 536 537 538 /** 539 Display the permit connect device path. 540 541 **/ 542 VOID 543 DisplayConnectPermit ( 544 VOID 545 ) 546 { 547 // 548 // Note: 549 // As no architect protocol/interface to be called in ConnectController() 550 // to verify the device path, just add a place holder for permitted connect 551 // device path. 552 // 553 } 554 555 556 /** 557 Display the forbid connect device path list. 558 559 **/ 560 VOID 561 DisplayConnectForbid ( 562 VOID 563 ) 564 { 565 // 566 // Note: 567 // As no architect protocol/interface to be called in ConnectController() 568 // to verify the device path, just add a place holder for forbidden connect 569 // device path. 570 // 571 } 572 573 574 /** 575 Delete the specified device path by DriverIndex from the forbid device path 576 list (mAccessInfo.LoadForbid). 577 578 @param[in] DriverIndex The index of driver in forbidden device path list. 579 580 **/ 581 VOID 582 DeleteFromForbidLoad ( 583 IN UINT16 DriverIndex 584 ) 585 { 586 UINTN OffSet; 587 UINTN DPSize; 588 UINTN OffLen; 589 EFI_DEVICE_PATH_PROTOCOL *Dp; 590 591 OffSet = 0; 592 // 593 // Find the specified device path. 594 // 595 while ((OffSet < mAccessInfo.LoadForbidLen) && (DriverIndex > 0)) { 596 Dp = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet); 597 DPSize = GetDevicePathSize (Dp); 598 OffSet += DPSize; 599 DriverIndex--; 600 } 601 602 // 603 // Specified device path found. 604 // 605 if (DriverIndex == 0) { 606 Dp = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet); 607 DPSize = GetDevicePathSize (Dp); 608 OffLen = mAccessInfo.LoadForbidLen - OffSet - DPSize; 609 if (OffLen > 0) { 610 CopyMem ( 611 mAccessInfo.LoadForbid + OffSet, 612 mAccessInfo.LoadForbid + OffSet + DPSize, 613 OffLen 614 ); 615 } 616 mAccessInfo.LoadForbidLen -= DPSize; 617 } 618 } 619 620 621 /** 622 Add the specified device path by DriverIndex to the forbid device path 623 list (mAccessInfo.LoadForbid). 624 625 @param[in] DriverIndex The index of driver saved in driver options. 626 627 **/ 628 VOID 629 AddToForbidLoad ( 630 IN UINT16 DriverIndex 631 ) 632 { 633 UINTN DevicePathLen; 634 UINT8 *Var; 635 UINT8 *VarPtr; 636 UINTN NewLen; 637 UINT8 *NewFL; 638 CHAR16 VarName[13]; 639 640 // 641 // Get loadable driver device path. 642 // 643 UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", DriverIndex); 644 GetEfiGlobalVariable2 (VarName, (VOID**)&Var, NULL); 645 if (Var == NULL) { 646 return; 647 } 648 649 // 650 // Save forbid load driver. 651 // 652 653 VarPtr = Var; 654 // 655 // Skip attribute. 656 // 657 VarPtr += sizeof (UINT32); 658 659 DevicePathLen = *(UINT16 *) VarPtr; 660 // 661 // Skip device path length. 662 // 663 VarPtr += sizeof (UINT16); 664 665 // 666 // Skip description string. 667 // 668 VarPtr += StrSize ((UINT16 *) VarPtr); 669 670 NewLen = mAccessInfo.LoadForbidLen + DevicePathLen; 671 NewFL = AllocateZeroPool (NewLen); 672 if (NewFL == NULL) { 673 FreePool (Var); 674 return ; 675 } 676 677 if (mAccessInfo.LoadForbidLen > 0) { 678 CopyMem (NewFL, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen); 679 FreePool (mAccessInfo.LoadForbid); 680 } 681 682 CopyMem (NewFL + mAccessInfo.LoadForbidLen, VarPtr, DevicePathLen); 683 mAccessInfo.LoadForbidLen = NewLen; 684 mAccessInfo.LoadForbid = NewFL; 685 FreePool (Var); 686 } 687 688 689