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