1 /* 2 * SAM Server DLL 3 * Copyright (C) 2005 Eric Kohl 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #include "samsrv.h" 21 22 #include <samsrv/samsrv.h> 23 24 /* GLOBALS *******************************************************************/ 25 26 ENCRYPTED_NT_OWF_PASSWORD EmptyNtHash; 27 ENCRYPTED_LM_OWF_PASSWORD EmptyLmHash; 28 RTL_RESOURCE SampResource; 29 NT_PRODUCT_TYPE SampProductType; 30 31 32 /* FUNCTIONS *****************************************************************/ 33 34 static 35 NTSTATUS 36 SampInitHashes(VOID) 37 { 38 UNICODE_STRING EmptyNtPassword = {0, 0, NULL}; 39 CHAR EmptyLmPassword[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}; 40 NTSTATUS Status; 41 42 /* Calculate the NT hash value of the empty password */ 43 Status = SystemFunction007(&EmptyNtPassword, 44 (LPBYTE)&EmptyNtHash); 45 if (!NT_SUCCESS(Status)) 46 { 47 ERR("Calculation of the empty NT hash failed (Status 0x%08lx)\n", Status); 48 return Status; 49 } 50 51 /* Calculate the LM hash value of the empty password */ 52 Status = SystemFunction006(EmptyLmPassword, 53 (LPSTR)&EmptyLmHash); 54 if (!NT_SUCCESS(Status)) 55 { 56 ERR("Calculation of the empty LM hash failed (Status 0x%08lx)\n", Status); 57 } 58 59 return Status; 60 } 61 62 63 NTSTATUS 64 NTAPI 65 SamIConnect(IN PSAMPR_SERVER_NAME ServerName, 66 OUT SAMPR_HANDLE *ServerHandle, 67 IN ACCESS_MASK DesiredAccess, 68 IN BOOLEAN Trusted) 69 { 70 PSAM_DB_OBJECT ServerObject; 71 NTSTATUS Status; 72 73 TRACE("SamIConnect(%p %p %lx %ld)\n", 74 ServerName, ServerHandle, DesiredAccess, Trusted); 75 76 /* Map generic access rights */ 77 RtlMapGenericMask(&DesiredAccess, 78 pServerMapping); 79 80 /* Open the Server Object */ 81 Status = SampOpenDbObject(NULL, 82 NULL, 83 L"SAM", 84 0, 85 SamDbServerObject, 86 DesiredAccess, 87 &ServerObject); 88 if (NT_SUCCESS(Status)) 89 { 90 ServerObject->Trusted = Trusted; 91 *ServerHandle = (SAMPR_HANDLE)ServerObject; 92 } 93 94 TRACE("SamIConnect done (Status 0x%08lx)\n", Status); 95 96 return Status; 97 } 98 99 100 NTSTATUS 101 NTAPI 102 SamIInitialize(VOID) 103 { 104 NTSTATUS Status = STATUS_SUCCESS; 105 106 TRACE("SamIInitialize() called\n"); 107 108 Status = RtlGetNtProductType(&SampProductType); 109 if (!NT_SUCCESS(Status)) 110 SampProductType = NtProductWinNt; 111 112 Status = SampInitHashes(); 113 if (!NT_SUCCESS(Status)) 114 return Status; 115 116 if (SampIsSetupRunning()) 117 { 118 Status = SampInitializeRegistry(); 119 if (!NT_SUCCESS(Status)) 120 return Status; 121 } 122 123 Status = SampInitializeDisplayCache(); 124 if (!NT_SUCCESS(Status)) 125 return Status; 126 127 RtlInitializeResource(&SampResource); 128 129 /* Initialize the SAM database */ 130 Status = SampInitDatabase(); 131 if (!NT_SUCCESS(Status)) 132 return Status; 133 134 /* Start the RPC server */ 135 SampStartRpcServer(); 136 137 return Status; 138 } 139 140 141 NTSTATUS 142 NTAPI 143 SampInitializeRegistry(VOID) 144 { 145 TRACE("SampInitializeRegistry() called\n"); 146 147 SampInitializeSAM(); 148 149 return STATUS_SUCCESS; 150 } 151 152 153 VOID 154 NTAPI 155 SamIFreeVoid(PVOID Ptr) 156 { 157 MIDL_user_free(Ptr); 158 } 159 160 161 VOID 162 NTAPI 163 SamIFree_SAMPR_ALIAS_INFO_BUFFER( 164 PSAMPR_ALIAS_INFO_BUFFER Ptr, 165 ALIAS_INFORMATION_CLASS InformationClass) 166 { 167 if (Ptr == NULL) 168 return; 169 170 switch (InformationClass) 171 { 172 case AliasGeneralInformation: 173 if (Ptr->General.Name.Buffer != NULL) 174 MIDL_user_free(Ptr->General.Name.Buffer); 175 176 if (Ptr->General.AdminComment.Buffer != NULL) 177 MIDL_user_free(Ptr->General.AdminComment.Buffer); 178 break; 179 180 case AliasNameInformation: 181 if (Ptr->Name.Name.Buffer != NULL) 182 MIDL_user_free(Ptr->Name.Name.Buffer); 183 break; 184 185 case AliasAdminCommentInformation: 186 if (Ptr->AdminComment.AdminComment.Buffer != NULL) 187 MIDL_user_free(Ptr->AdminComment.AdminComment.Buffer); 188 break; 189 190 default: 191 FIXME("Unsupported information class: %lu\n", InformationClass); 192 break; 193 } 194 195 MIDL_user_free(Ptr); 196 } 197 198 199 VOID 200 NTAPI 201 SamIFree_SAMPR_DISPLAY_INFO_BUFFER( 202 PSAMPR_DISPLAY_INFO_BUFFER Ptr, 203 DOMAIN_DISPLAY_INFORMATION InformationClass) 204 { 205 ULONG i; 206 207 if (Ptr == NULL) 208 return; 209 210 switch (InformationClass) 211 { 212 case DomainDisplayUser: 213 if (Ptr->UserInformation.Buffer != NULL) 214 { 215 for (i = 0; i < Ptr->UserInformation.EntriesRead; i++) 216 { 217 if (Ptr->UserInformation.Buffer[i].AccountName.Buffer != NULL) 218 MIDL_user_free(Ptr->UserInformation.Buffer[i].AccountName.Buffer); 219 220 if (Ptr->UserInformation.Buffer[i].AdminComment.Buffer != NULL) 221 MIDL_user_free(Ptr->UserInformation.Buffer[i].AdminComment.Buffer); 222 223 if (Ptr->UserInformation.Buffer[i].FullName.Buffer != NULL) 224 MIDL_user_free(Ptr->UserInformation.Buffer[i].FullName.Buffer); 225 } 226 227 MIDL_user_free(Ptr->UserInformation.Buffer); 228 } 229 break; 230 231 case DomainDisplayMachine: 232 if (Ptr->MachineInformation.Buffer != NULL) 233 { 234 for (i = 0; i < Ptr->MachineInformation.EntriesRead; i++) 235 { 236 if (Ptr->MachineInformation.Buffer[i].AccountName.Buffer != NULL) 237 MIDL_user_free(Ptr->MachineInformation.Buffer[i].AccountName.Buffer); 238 239 if (Ptr->MachineInformation.Buffer[i].AdminComment.Buffer != NULL) 240 MIDL_user_free(Ptr->MachineInformation.Buffer[i].AdminComment.Buffer); 241 } 242 243 MIDL_user_free(Ptr->MachineInformation.Buffer); 244 } 245 break; 246 247 case DomainDisplayGroup: 248 if (Ptr->GroupInformation.Buffer != NULL) 249 { 250 for (i = 0; i < Ptr->GroupInformation.EntriesRead; i++) 251 { 252 if (Ptr->GroupInformation.Buffer[i].AccountName.Buffer != NULL) 253 MIDL_user_free(Ptr->GroupInformation.Buffer[i].AccountName.Buffer); 254 255 if (Ptr->GroupInformation.Buffer[i].AdminComment.Buffer != NULL) 256 MIDL_user_free(Ptr->GroupInformation.Buffer[i].AdminComment.Buffer); 257 } 258 259 MIDL_user_free(Ptr->GroupInformation.Buffer); 260 } 261 break; 262 263 case DomainDisplayOemUser: 264 if (Ptr->OemUserInformation.Buffer != NULL) 265 { 266 for (i = 0; i < Ptr->OemUserInformation.EntriesRead; i++) 267 { 268 if (Ptr->OemUserInformation.Buffer[i].OemAccountName.Buffer != NULL) 269 MIDL_user_free(Ptr->OemUserInformation.Buffer[i].OemAccountName.Buffer); 270 } 271 272 MIDL_user_free(Ptr->OemUserInformation.Buffer); 273 } 274 break; 275 276 case DomainDisplayOemGroup: 277 if (Ptr->OemGroupInformation.Buffer != NULL) 278 { 279 for (i = 0; i < Ptr->OemGroupInformation.EntriesRead; i++) 280 { 281 if (Ptr->OemGroupInformation.Buffer[i].OemAccountName.Buffer != NULL) 282 MIDL_user_free(Ptr->OemGroupInformation.Buffer[i].OemAccountName.Buffer); 283 } 284 285 MIDL_user_free(Ptr->OemGroupInformation.Buffer); 286 } 287 break; 288 289 default: 290 FIXME("Unsupported information class: %lu\n", InformationClass); 291 break; 292 } 293 } 294 295 296 VOID 297 NTAPI 298 SamIFree_SAMPR_DOMAIN_INFO_BUFFER( 299 PSAMPR_DOMAIN_INFO_BUFFER Ptr, 300 DOMAIN_INFORMATION_CLASS InformationClass) 301 { 302 if (Ptr == NULL) 303 return; 304 305 switch (InformationClass) 306 { 307 case DomainPasswordInformation: 308 break; 309 310 case DomainGeneralInformation: 311 if (Ptr->General.OemInformation.Buffer != NULL) 312 MIDL_user_free(Ptr->General.OemInformation.Buffer); 313 314 if (Ptr->General.DomainName.Buffer != NULL) 315 MIDL_user_free(Ptr->General.DomainName.Buffer); 316 317 if (Ptr->General.ReplicaSourceNodeName.Buffer != NULL) 318 MIDL_user_free(Ptr->General.ReplicaSourceNodeName.Buffer); 319 break; 320 321 case DomainLogoffInformation: 322 break; 323 324 case DomainOemInformation: 325 if (Ptr->Oem.OemInformation.Buffer != NULL) 326 MIDL_user_free(Ptr->Oem.OemInformation.Buffer); 327 break; 328 329 case DomainNameInformation: 330 if (Ptr->Name.DomainName.Buffer != NULL) 331 MIDL_user_free(Ptr->Name.DomainName.Buffer); 332 break; 333 334 case DomainReplicationInformation: 335 if (Ptr->Replication.ReplicaSourceNodeName.Buffer != NULL) 336 MIDL_user_free(Ptr->Replication.ReplicaSourceNodeName.Buffer); 337 break; 338 339 case DomainServerRoleInformation: 340 break; 341 342 case DomainModifiedInformation: 343 break; 344 345 case DomainStateInformation: 346 break; 347 348 case DomainGeneralInformation2: 349 if (Ptr->General2.I1.OemInformation.Buffer != NULL) 350 MIDL_user_free(Ptr->General2.I1.OemInformation.Buffer); 351 352 if (Ptr->General2.I1.DomainName.Buffer != NULL) 353 MIDL_user_free(Ptr->General2.I1.DomainName.Buffer); 354 355 if (Ptr->General2.I1.ReplicaSourceNodeName.Buffer != NULL) 356 MIDL_user_free(Ptr->General2.I1.ReplicaSourceNodeName.Buffer); 357 break; 358 359 case DomainLockoutInformation: 360 break; 361 362 case DomainModifiedInformation2: 363 break; 364 365 default: 366 FIXME("Unsupported information class: %lu\n", InformationClass); 367 break; 368 } 369 370 MIDL_user_free(Ptr); 371 } 372 373 374 VOID 375 NTAPI 376 SamIFree_SAMPR_ENUMERATION_BUFFER(PSAMPR_ENUMERATION_BUFFER Ptr) 377 { 378 ULONG i; 379 380 if (Ptr == NULL) 381 return; 382 383 if (Ptr->Buffer != NULL) 384 { 385 for (i = 0; i < Ptr->EntriesRead; i++) 386 { 387 if (Ptr->Buffer[i].Name.Buffer != NULL) 388 MIDL_user_free(Ptr->Buffer[i].Name.Buffer); 389 } 390 391 MIDL_user_free(Ptr->Buffer); 392 } 393 394 MIDL_user_free(Ptr); 395 } 396 397 398 VOID 399 NTAPI 400 SamIFree_SAMPR_GET_GROUPS_BUFFER(PSAMPR_GET_GROUPS_BUFFER Ptr) 401 { 402 if (Ptr == NULL) 403 return; 404 405 if (Ptr->Groups != NULL) 406 MIDL_user_free(Ptr->Groups); 407 408 MIDL_user_free(Ptr); 409 } 410 411 412 VOID 413 NTAPI 414 SamIFree_SAMPR_GET_MEMBERS_BUFFER(PSAMPR_GET_MEMBERS_BUFFER Ptr) 415 { 416 if (Ptr == NULL) 417 return; 418 419 if (Ptr->Members != NULL) 420 MIDL_user_free(Ptr->Members); 421 422 if (Ptr->Attributes != NULL) 423 MIDL_user_free(Ptr->Attributes); 424 425 MIDL_user_free(Ptr); 426 } 427 428 429 VOID 430 NTAPI 431 SamIFree_SAMPR_GROUP_INFO_BUFFER( 432 PSAMPR_GROUP_INFO_BUFFER Ptr, 433 GROUP_INFORMATION_CLASS InformationClass) 434 { 435 if (Ptr == NULL) 436 return; 437 438 switch (InformationClass) 439 { 440 case GroupGeneralInformation: 441 if (Ptr->General.Name.Buffer != NULL) 442 MIDL_user_free(Ptr->General.Name.Buffer); 443 444 if (Ptr->General.AdminComment.Buffer != NULL) 445 MIDL_user_free(Ptr->General.AdminComment.Buffer); 446 break; 447 448 case GroupNameInformation: 449 if (Ptr->Name.Name.Buffer != NULL) 450 MIDL_user_free(Ptr->Name.Name.Buffer); 451 break; 452 453 case GroupAttributeInformation: 454 break; 455 456 case GroupAdminCommentInformation: 457 if (Ptr->AdminComment.AdminComment.Buffer != NULL) 458 MIDL_user_free(Ptr->AdminComment.AdminComment.Buffer); 459 break; 460 461 default: 462 FIXME("Unsupported information class: %lu\n", InformationClass); 463 break; 464 } 465 466 MIDL_user_free(Ptr); 467 } 468 469 470 VOID 471 NTAPI 472 SamIFree_SAMPR_PSID_ARRAY(PSAMPR_PSID_ARRAY Ptr) 473 { 474 if (Ptr == NULL) 475 return; 476 477 if (Ptr->Sids != NULL) 478 { 479 MIDL_user_free(Ptr->Sids); 480 } 481 } 482 483 484 VOID 485 NTAPI 486 SamIFree_SAMPR_RETURNED_USTRING_ARRAY(PSAMPR_RETURNED_USTRING_ARRAY Ptr) 487 { 488 ULONG i; 489 490 if (Ptr == NULL) 491 return; 492 493 if (Ptr->Element != NULL) 494 { 495 for (i = 0; i < Ptr->Count; i++) 496 { 497 if (Ptr->Element[i].Buffer != NULL) 498 MIDL_user_free(Ptr->Element[i].Buffer); 499 } 500 501 MIDL_user_free(Ptr->Element); 502 Ptr->Element = NULL; 503 Ptr->Count = 0; 504 } 505 } 506 507 508 VOID 509 NTAPI 510 SamIFree_SAMPR_SR_SECURITY_DESCRIPTOR(PSAMPR_SR_SECURITY_DESCRIPTOR Ptr) 511 { 512 if (Ptr == NULL) 513 return; 514 515 if (Ptr->SecurityDescriptor != NULL) 516 MIDL_user_free(Ptr->SecurityDescriptor); 517 518 MIDL_user_free(Ptr); 519 } 520 521 522 VOID 523 NTAPI 524 SamIFree_SAMPR_ULONG_ARRAY(PSAMPR_ULONG_ARRAY Ptr) 525 { 526 if (Ptr == NULL) 527 return; 528 529 if (Ptr->Element != NULL) 530 { 531 MIDL_user_free(Ptr->Element); 532 Ptr->Element = NULL; 533 Ptr->Count = 0; 534 } 535 } 536 537 538 VOID 539 NTAPI 540 SamIFree_SAMPR_USER_INFO_BUFFER(PSAMPR_USER_INFO_BUFFER Ptr, 541 USER_INFORMATION_CLASS InformationClass) 542 { 543 if (Ptr == NULL) 544 return; 545 546 switch (InformationClass) 547 { 548 case UserGeneralInformation: 549 if (Ptr->General.UserName.Buffer != NULL) 550 MIDL_user_free(Ptr->General.UserName.Buffer); 551 552 if (Ptr->General.FullName.Buffer != NULL) 553 MIDL_user_free(Ptr->General.FullName.Buffer); 554 555 if (Ptr->General.AdminComment.Buffer != NULL) 556 MIDL_user_free(Ptr->General.AdminComment.Buffer); 557 558 if (Ptr->General.UserComment.Buffer != NULL) 559 MIDL_user_free(Ptr->General.UserComment.Buffer); 560 break; 561 562 case UserPreferencesInformation: 563 if (Ptr->Preferences.UserComment.Buffer != NULL) 564 MIDL_user_free(Ptr->Preferences.UserComment.Buffer); 565 566 if (Ptr->Preferences.Reserved1.Buffer != NULL) 567 MIDL_user_free(Ptr->Preferences.Reserved1.Buffer); 568 break; 569 570 case UserLogonInformation: 571 if (Ptr->Logon.UserName.Buffer != NULL) 572 MIDL_user_free(Ptr->Logon.UserName.Buffer); 573 574 if (Ptr->Logon.FullName.Buffer != NULL) 575 MIDL_user_free(Ptr->Logon.FullName.Buffer); 576 577 if (Ptr->Logon.HomeDirectory.Buffer != NULL) 578 MIDL_user_free(Ptr->Logon.HomeDirectory.Buffer); 579 580 if (Ptr->Logon.HomeDirectoryDrive.Buffer != NULL) 581 MIDL_user_free(Ptr->Logon.HomeDirectoryDrive.Buffer); 582 583 if (Ptr->Logon.ScriptPath.Buffer != NULL) 584 MIDL_user_free(Ptr->Logon.ScriptPath.Buffer); 585 586 if (Ptr->Logon.ProfilePath.Buffer != NULL) 587 MIDL_user_free(Ptr->Logon.ProfilePath.Buffer); 588 589 if (Ptr->Logon.WorkStations.Buffer != NULL) 590 MIDL_user_free(Ptr->Logon.WorkStations.Buffer); 591 592 if (Ptr->Logon.LogonHours.LogonHours != NULL) 593 MIDL_user_free(Ptr->Logon.LogonHours.LogonHours); 594 break; 595 596 case UserLogonHoursInformation: 597 if (Ptr->LogonHours.LogonHours.LogonHours != NULL) 598 MIDL_user_free(Ptr->LogonHours.LogonHours.LogonHours); 599 break; 600 601 case UserAccountInformation: 602 if (Ptr->Account.UserName.Buffer != NULL) 603 MIDL_user_free(Ptr->Account.UserName.Buffer); 604 605 if (Ptr->Account.FullName.Buffer != NULL) 606 MIDL_user_free(Ptr->Account.FullName.Buffer); 607 608 if (Ptr->Account.HomeDirectory.Buffer != NULL) 609 MIDL_user_free(Ptr->Account.HomeDirectory.Buffer); 610 611 if (Ptr->Account.HomeDirectoryDrive.Buffer != NULL) 612 MIDL_user_free(Ptr->Account.HomeDirectoryDrive.Buffer); 613 614 if (Ptr->Account.ScriptPath.Buffer != NULL) 615 MIDL_user_free(Ptr->Account.ScriptPath.Buffer); 616 617 if (Ptr->Account.ProfilePath.Buffer != NULL) 618 MIDL_user_free(Ptr->Account.ProfilePath.Buffer); 619 620 if (Ptr->Account.AdminComment.Buffer != NULL) 621 MIDL_user_free(Ptr->Account.AdminComment.Buffer); 622 623 if (Ptr->Account.WorkStations.Buffer != NULL) 624 MIDL_user_free(Ptr->Account.WorkStations.Buffer); 625 626 if (Ptr->Account.LogonHours.LogonHours != NULL) 627 MIDL_user_free(Ptr->Account.LogonHours.LogonHours); 628 break; 629 630 case UserNameInformation: 631 if (Ptr->Name.UserName.Buffer != NULL) 632 MIDL_user_free(Ptr->Name.UserName.Buffer); 633 634 if (Ptr->Name.FullName.Buffer != NULL) 635 MIDL_user_free(Ptr->Name.FullName.Buffer); 636 break; 637 638 case UserAccountNameInformation: 639 if (Ptr->AccountName.UserName.Buffer != NULL) 640 MIDL_user_free(Ptr->AccountName.UserName.Buffer); 641 break; 642 643 case UserFullNameInformation: 644 if (Ptr->FullName.FullName.Buffer != NULL) 645 MIDL_user_free(Ptr->FullName.FullName.Buffer); 646 break; 647 648 case UserPrimaryGroupInformation: 649 break; 650 651 case UserHomeInformation: 652 if (Ptr->Home.HomeDirectory.Buffer != NULL) 653 MIDL_user_free(Ptr->Home.HomeDirectory.Buffer); 654 655 if (Ptr->Home.HomeDirectoryDrive.Buffer != NULL) 656 MIDL_user_free(Ptr->Home.HomeDirectoryDrive.Buffer); 657 break; 658 659 case UserScriptInformation: 660 if (Ptr->Script.ScriptPath.Buffer != NULL) 661 MIDL_user_free(Ptr->Script.ScriptPath.Buffer); 662 break; 663 664 case UserProfileInformation: 665 if (Ptr->Profile.ProfilePath.Buffer != NULL) 666 MIDL_user_free(Ptr->Profile.ProfilePath.Buffer); 667 break; 668 669 case UserAdminCommentInformation: 670 if (Ptr->AdminComment.AdminComment.Buffer != NULL) 671 MIDL_user_free(Ptr->AdminComment.AdminComment.Buffer); 672 break; 673 674 case UserWorkStationsInformation: 675 if (Ptr->WorkStations.WorkStations.Buffer != NULL) 676 MIDL_user_free(Ptr->WorkStations.WorkStations.Buffer); 677 break; 678 679 case UserSetPasswordInformation: 680 ERR("Information class UserSetPasswordInformation cannot be queried!\n"); 681 break; 682 683 case UserControlInformation: 684 break; 685 686 case UserExpiresInformation: 687 break; 688 689 case UserInternal1Information: 690 break; 691 692 case UserInternal2Information: 693 break; 694 695 case UserParametersInformation: 696 if (Ptr->Parameters.Parameters.Buffer != NULL) 697 MIDL_user_free(Ptr->Parameters.Parameters.Buffer); 698 break; 699 700 case UserAllInformation: 701 if (Ptr->All.UserName.Buffer != NULL) 702 MIDL_user_free(Ptr->All.UserName.Buffer); 703 704 if (Ptr->All.FullName.Buffer != NULL) 705 MIDL_user_free(Ptr->All.FullName.Buffer); 706 707 if (Ptr->All.HomeDirectory.Buffer != NULL) 708 MIDL_user_free(Ptr->All.HomeDirectory.Buffer); 709 710 if (Ptr->All.HomeDirectoryDrive.Buffer != NULL) 711 MIDL_user_free(Ptr->All.HomeDirectoryDrive.Buffer); 712 713 if (Ptr->All.ScriptPath.Buffer != NULL) 714 MIDL_user_free(Ptr->All.ScriptPath.Buffer); 715 716 if (Ptr->All.ProfilePath.Buffer != NULL) 717 MIDL_user_free(Ptr->All.ProfilePath.Buffer); 718 719 if (Ptr->All.AdminComment.Buffer != NULL) 720 MIDL_user_free(Ptr->All.AdminComment.Buffer); 721 722 if (Ptr->All.WorkStations.Buffer != NULL) 723 MIDL_user_free(Ptr->All.WorkStations.Buffer); 724 725 if (Ptr->All.UserComment.Buffer != NULL) 726 MIDL_user_free(Ptr->All.UserComment.Buffer); 727 728 if (Ptr->All.Parameters.Buffer != NULL) 729 MIDL_user_free(Ptr->All.Parameters.Buffer); 730 731 if (Ptr->All.LmOwfPassword.Buffer != NULL) 732 MIDL_user_free(Ptr->All.LmOwfPassword.Buffer); 733 734 if (Ptr->All.NtOwfPassword.Buffer != NULL) 735 MIDL_user_free(Ptr->All.NtOwfPassword.Buffer); 736 737 if (Ptr->All.PrivateData.Buffer != NULL) 738 MIDL_user_free(Ptr->All.PrivateData.Buffer); 739 740 if (Ptr->All.SecurityDescriptor.SecurityDescriptor != NULL) 741 MIDL_user_free(Ptr->All.SecurityDescriptor.SecurityDescriptor); 742 743 if (Ptr->All.LogonHours.LogonHours != NULL) 744 MIDL_user_free(Ptr->All.LogonHours.LogonHours); 745 break; 746 747 default: 748 FIXME("Unsupported information class: %lu\n", InformationClass); 749 break; 750 } 751 752 MIDL_user_free(Ptr); 753 } 754 755 /* EOF */ 756