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