diff options
| -rw-r--r-- | src/ext/Util/ca/precomp.h | 3 | ||||
| -rw-r--r-- | src/ext/Util/ca/scaexec.cpp | 100 | ||||
| -rw-r--r-- | src/ext/Util/ca/scauser.cpp | 48 | ||||
| -rw-r--r-- | src/ext/Util/ca/utilca.cpp | 56 | ||||
| -rw-r--r-- | src/ext/Util/ca/utilca.h | 8 |
5 files changed, 95 insertions, 120 deletions
diff --git a/src/ext/Util/ca/precomp.h b/src/ext/Util/ca/precomp.h index efde32a6..9456c691 100644 --- a/src/ext/Util/ca/precomp.h +++ b/src/ext/Util/ca/precomp.h | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | #include <msxml2.h> | 16 | #include <msxml2.h> |
| 17 | #include <Iads.h> | 17 | #include <Iads.h> |
| 18 | #include <activeds.h> | 18 | #include <activeds.h> |
| 19 | #include <lm.h> // NetApi32.lib | 19 | #include <lm.h> // NetApi32.lib |
| 20 | #include <Ntsecapi.h> | 20 | #include <Ntsecapi.h> |
| 21 | #include <Dsgetdc.h> | 21 | #include <Dsgetdc.h> |
| @@ -50,5 +50,6 @@ | |||
| 50 | #include "scauser.h" | 50 | #include "scauser.h" |
| 51 | #include "scasmb.h" | 51 | #include "scasmb.h" |
| 52 | #include "scasmbexec.h" | 52 | #include "scasmbexec.h" |
| 53 | #include "utilca.h" | ||
| 53 | 54 | ||
| 54 | #include "..\..\caDecor.h" | 55 | #include "..\..\caDecor.h" |
diff --git a/src/ext/Util/ca/scaexec.cpp b/src/ext/Util/ca/scaexec.cpp index 5119bc11..8579b8bb 100644 --- a/src/ext/Util/ca/scaexec.cpp +++ b/src/ext/Util/ca/scaexec.cpp | |||
| @@ -613,8 +613,7 @@ static HRESULT RemoveUserInternal( | |||
| 613 | LPWSTR pwz = NULL; | 613 | LPWSTR pwz = NULL; |
| 614 | LPWSTR pwzGroup = NULL; | 614 | LPWSTR pwzGroup = NULL; |
| 615 | LPWSTR pwzGroupDomain = NULL; | 615 | LPWSTR pwzGroupDomain = NULL; |
| 616 | LPCWSTR wz = NULL; | 616 | LPWSTR pwzDomainName = NULL; |
| 617 | PDOMAIN_CONTROLLER_INFOW pDomainControllerInfo = NULL; | ||
| 618 | 617 | ||
| 619 | // | 618 | // |
| 620 | // Remove the logon as service privilege. | 619 | // Remove the logon as service privilege. |
| @@ -644,30 +643,10 @@ static HRESULT RemoveUserInternal( | |||
| 644 | // | 643 | // |
| 645 | if (!(SCAU_DONT_CREATE_USER & iAttributes)) | 644 | if (!(SCAU_DONT_CREATE_USER & iAttributes)) |
| 646 | { | 645 | { |
| 647 | if (wzDomain && *wzDomain) | 646 | hr = GetDomainFromServerName(&pwzDomainName, wzDomain, 0); |
| 648 | { | 647 | ExitOnFailure(hr, "Failed to get domain to remove user from server name: %ls", wzDomain); |
| 649 | er = ::DsGetDcNameW(NULL, (LPCWSTR)wzDomain, NULL, NULL, NULL, &pDomainControllerInfo); | ||
| 650 | if (RPC_S_SERVER_UNAVAILABLE == er) | ||
| 651 | { | ||
| 652 | // MSDN says, if we get the above error code, try again with the "DS_FORCE_REDISCOVERY" flag | ||
| 653 | er = ::DsGetDcNameW(NULL, (LPCWSTR)wzDomain, NULL, NULL, DS_FORCE_REDISCOVERY, &pDomainControllerInfo); | ||
| 654 | } | ||
| 655 | if (ERROR_SUCCESS == er) | ||
| 656 | { | ||
| 657 | if (2 <= wcslen(pDomainControllerInfo->DomainControllerName)) | ||
| 658 | { | ||
| 659 | wz = pDomainControllerInfo->DomainControllerName + 2; // Add 2 so that we don't get the \\ prefix. | ||
| 660 | // Pass the entire string if it is too short | ||
| 661 | // to have a \\ prefix. | ||
| 662 | } | ||
| 663 | } | ||
| 664 | else | ||
| 665 | { | ||
| 666 | wz = wzDomain; | ||
| 667 | } | ||
| 668 | } | ||
| 669 | 648 | ||
| 670 | er = ::NetUserDel(wz, wzName); | 649 | er = ::NetUserDel(pwzDomainName, wzName); |
| 671 | if (NERR_UserNotFound == er) | 650 | if (NERR_UserNotFound == er) |
| 672 | { | 651 | { |
| 673 | er = NERR_Success; | 652 | er = NERR_Success; |
| @@ -707,52 +686,13 @@ static HRESULT RemoveUserInternal( | |||
| 707 | } | 686 | } |
| 708 | 687 | ||
| 709 | LExit: | 688 | LExit: |
| 710 | if (pDomainControllerInfo) | 689 | ReleaseStr(pwzDomainName); |
| 711 | { | 690 | ReleaseStr(pwzGroupDomain); |
| 712 | ::NetApiBufferFree(static_cast<LPVOID>(pDomainControllerInfo)); | 691 | ReleaseStr(pwzGroup); |
| 713 | } | ||
| 714 | 692 | ||
| 715 | return hr; | 693 | return hr; |
| 716 | } | 694 | } |
| 717 | 695 | ||
| 718 | static void GetServerName(LPWSTR pwzDomain, LPWSTR* ppwzServerName) | ||
| 719 | { | ||
| 720 | DWORD er = ERROR_SUCCESS; | ||
| 721 | PDOMAIN_CONTROLLER_INFOW pDomainControllerInfo = NULL; | ||
| 722 | |||
| 723 | if (pwzDomain && *pwzDomain) | ||
| 724 | { | ||
| 725 | er = ::DsGetDcNameW(NULL, (LPCWSTR)pwzDomain, NULL, NULL, NULL, &pDomainControllerInfo); | ||
| 726 | if (RPC_S_SERVER_UNAVAILABLE == er) | ||
| 727 | { | ||
| 728 | // MSDN says, if we get the above error code, try again with the "DS_FORCE_REDISCOVERY" flag | ||
| 729 | er = ::DsGetDcNameW(NULL, (LPCWSTR)pwzDomain, NULL, NULL, DS_FORCE_REDISCOVERY, &pDomainControllerInfo); | ||
| 730 | } | ||
| 731 | |||
| 732 | if (ERROR_SUCCESS == er && pDomainControllerInfo->DomainControllerName) | ||
| 733 | { | ||
| 734 | // Skip the \\ prefix if present. | ||
| 735 | if ('\\' == *pDomainControllerInfo->DomainControllerName && '\\' == *pDomainControllerInfo->DomainControllerName + 1) | ||
| 736 | { | ||
| 737 | *ppwzServerName = pDomainControllerInfo->DomainControllerName + 2; | ||
| 738 | } | ||
| 739 | else | ||
| 740 | { | ||
| 741 | *ppwzServerName = pDomainControllerInfo->DomainControllerName; | ||
| 742 | } | ||
| 743 | } | ||
| 744 | else | ||
| 745 | { | ||
| 746 | *ppwzServerName = pwzDomain; | ||
| 747 | } | ||
| 748 | } | ||
| 749 | |||
| 750 | if (pDomainControllerInfo) | ||
| 751 | { | ||
| 752 | ::NetApiBufferFree((LPVOID)pDomainControllerInfo); | ||
| 753 | } | ||
| 754 | } | ||
| 755 | |||
| 756 | /******************************************************************** | 696 | /******************************************************************** |
| 757 | CreateUser - CUSTOM ACTION ENTRY POINT for creating users | 697 | CreateUser - CUSTOM ACTION ENTRY POINT for creating users |
| 758 | 698 | ||
| @@ -776,6 +716,7 @@ extern "C" UINT __stdcall CreateUser( | |||
| 776 | LPWSTR pwzPassword = NULL; | 716 | LPWSTR pwzPassword = NULL; |
| 777 | LPWSTR pwzGroup = NULL; | 717 | LPWSTR pwzGroup = NULL; |
| 778 | LPWSTR pwzGroupDomain = NULL; | 718 | LPWSTR pwzGroupDomain = NULL; |
| 719 | LPWSTR pwzDomainName = NULL; | ||
| 779 | int iAttributes = 0; | 720 | int iAttributes = 0; |
| 780 | BOOL fInitializedCom = FALSE; | 721 | BOOL fInitializedCom = FALSE; |
| 781 | 722 | ||
| @@ -786,7 +727,6 @@ extern "C" UINT __stdcall CreateUser( | |||
| 786 | USER_INFO_1 userInfo1; | 727 | USER_INFO_1 userInfo1; |
| 787 | USER_INFO_1* pUserInfo1 = NULL; | 728 | USER_INFO_1* pUserInfo1 = NULL; |
| 788 | DWORD dw; | 729 | DWORD dw; |
| 789 | LPWSTR pwzServerName = NULL; | ||
| 790 | 730 | ||
| 791 | hr = WcaInitialize(hInstall, "CreateUser"); | 731 | hr = WcaInitialize(hInstall, "CreateUser"); |
| 792 | ExitOnFailure(hr, "failed to initialize"); | 732 | ExitOnFailure(hr, "failed to initialize"); |
| @@ -845,9 +785,10 @@ extern "C" UINT __stdcall CreateUser( | |||
| 845 | // | 785 | // |
| 846 | // Create the User | 786 | // Create the User |
| 847 | // | 787 | // |
| 848 | GetServerName(pwzDomain, &pwzServerName); | 788 | hr = GetDomainFromServerName(&pwzDomainName, pwzDomain, 0); |
| 789 | ExitOnFailure(hr, "Failed to get domain from server name: %ls", pwzDomain); | ||
| 849 | 790 | ||
| 850 | er = ::NetUserAdd(pwzServerName, 1, reinterpret_cast<LPBYTE>(pUserInfo1), &dw); | 791 | er = ::NetUserAdd(pwzDomainName, 1, reinterpret_cast<LPBYTE>(pUserInfo1), &dw); |
| 851 | if (NERR_UserExists == er) | 792 | if (NERR_UserExists == er) |
| 852 | { | 793 | { |
| 853 | if (SCAU_FAIL_IF_EXISTS & iAttributes) | 794 | if (SCAU_FAIL_IF_EXISTS & iAttributes) |
| @@ -862,7 +803,7 @@ extern "C" UINT __stdcall CreateUser( | |||
| 862 | if (SCAU_UPDATE_IF_EXISTS & iAttributes) | 803 | if (SCAU_UPDATE_IF_EXISTS & iAttributes) |
| 863 | { | 804 | { |
| 864 | pUserInfo1 = NULL; | 805 | pUserInfo1 = NULL; |
| 865 | er = ::NetUserGetInfo(pwzServerName, pwzName, 1, reinterpret_cast<LPBYTE*>(&pUserInfo1)); | 806 | er = ::NetUserGetInfo(pwzDomainName, pwzName, 1, reinterpret_cast<LPBYTE*>(&pUserInfo1)); |
| 866 | if (ERROR_SUCCESS == er) | 807 | if (ERROR_SUCCESS == er) |
| 867 | { | 808 | { |
| 868 | // There is no rollback scheduled if the key is empty. | 809 | // There is no rollback scheduled if the key is empty. |
| @@ -922,28 +863,28 @@ extern "C" UINT __stdcall CreateUser( | |||
| 922 | 863 | ||
| 923 | if (ERROR_SUCCESS == er) | 864 | if (ERROR_SUCCESS == er) |
| 924 | { | 865 | { |
| 925 | hr = SetUserPassword(pwzServerName, pwzName, pwzPassword); | 866 | hr = SetUserPassword(pwzDomainName, pwzName, pwzPassword); |
| 926 | if (FAILED(hr)) | 867 | if (FAILED(hr)) |
| 927 | { | 868 | { |
| 928 | WcaLogError(hr, "failed to set user password for user %ls\\%ls, continuing anyway.", pwzServerName, pwzName); | 869 | WcaLogError(hr, "failed to set user password for user %ls\\%ls, continuing anyway.", pwzDomainName, pwzName); |
| 929 | hr = S_OK; | 870 | hr = S_OK; |
| 930 | } | 871 | } |
| 931 | 872 | ||
| 932 | if (SCAU_REMOVE_COMMENT & iAttributes) | 873 | if (SCAU_REMOVE_COMMENT & iAttributes) |
| 933 | { | 874 | { |
| 934 | hr = SetUserComment(pwzServerName, pwzName, L""); | 875 | hr = SetUserComment(pwzDomainName, pwzName, L""); |
| 935 | if (FAILED(hr)) | 876 | if (FAILED(hr)) |
| 936 | { | 877 | { |
| 937 | WcaLogError(hr, "failed to clear user comment for user %ls\\%ls, continuing anyway.", pwzServerName, pwzName); | 878 | WcaLogError(hr, "failed to clear user comment for user %ls\\%ls, continuing anyway.", pwzDomainName, pwzName); |
| 938 | hr = S_OK; | 879 | hr = S_OK; |
| 939 | } | 880 | } |
| 940 | } | 881 | } |
| 941 | else if (pwzComment && *pwzComment) | 882 | else if (pwzComment && *pwzComment) |
| 942 | { | 883 | { |
| 943 | hr = SetUserComment(pwzServerName, pwzName, pwzComment); | 884 | hr = SetUserComment(pwzDomainName, pwzName, pwzComment); |
| 944 | if (FAILED(hr)) | 885 | if (FAILED(hr)) |
| 945 | { | 886 | { |
| 946 | WcaLogError(hr, "failed to set user comment to %ls for user %ls\\%ls, continuing anyway.", pwzComment, pwzServerName, pwzName); | 887 | WcaLogError(hr, "failed to set user comment to %ls for user %ls\\%ls, continuing anyway.", pwzComment, pwzDomainName, pwzName); |
| 947 | hr = S_OK; | 888 | hr = S_OK; |
| 948 | } | 889 | } |
| 949 | } | 890 | } |
| @@ -952,10 +893,10 @@ extern "C" UINT __stdcall CreateUser( | |||
| 952 | 893 | ||
| 953 | ApplyAttributes(iAttributes, &flags); | 894 | ApplyAttributes(iAttributes, &flags); |
| 954 | 895 | ||
| 955 | hr = SetUserFlags(pwzServerName, pwzName, flags); | 896 | hr = SetUserFlags(pwzDomainName, pwzName, flags); |
| 956 | if (FAILED(hr)) | 897 | if (FAILED(hr)) |
| 957 | { | 898 | { |
| 958 | WcaLogError(hr, "failed to set user flags for user %ls\\%ls, continuing anyway.", pwzServerName, pwzName); | 899 | WcaLogError(hr, "failed to set user flags for user %ls\\%ls, continuing anyway.", pwzDomainName, pwzName); |
| 959 | hr = S_OK; | 900 | hr = S_OK; |
| 960 | } | 901 | } |
| 961 | } | 902 | } |
| @@ -1018,6 +959,7 @@ LExit: | |||
| 1018 | ReleaseStr(pwzPassword); | 959 | ReleaseStr(pwzPassword); |
| 1019 | ReleaseStr(pwzGroup); | 960 | ReleaseStr(pwzGroup); |
| 1020 | ReleaseStr(pwzGroupDomain); | 961 | ReleaseStr(pwzGroupDomain); |
| 962 | ReleaseStr(pwzDomainName) | ||
| 1021 | 963 | ||
| 1022 | if (fInitializedCom) | 964 | if (fInitializedCom) |
| 1023 | { | 965 | { |
diff --git a/src/ext/Util/ca/scauser.cpp b/src/ext/Util/ca/scauser.cpp index b643a842..79da155f 100644 --- a/src/ext/Util/ca/scauser.cpp +++ b/src/ext/Util/ca/scauser.cpp | |||
| @@ -487,7 +487,7 @@ HRESULT ScaUserExecute( | |||
| 487 | { | 487 | { |
| 488 | HRESULT hr = S_OK; | 488 | HRESULT hr = S_OK; |
| 489 | DWORD er = 0; | 489 | DWORD er = 0; |
| 490 | PDOMAIN_CONTROLLER_INFOW pDomainControllerInfo = NULL; | 490 | LPWSTR pwzDomainName = NULL; |
| 491 | 491 | ||
| 492 | LPWSTR pwzBaseScriptKey = NULL; | 492 | LPWSTR pwzBaseScriptKey = NULL; |
| 493 | DWORD cScriptKey = 0; | 493 | DWORD cScriptKey = 0; |
| @@ -518,36 +518,11 @@ HRESULT ScaUserExecute( | |||
| 518 | ExitOnFailure(hr, "Failed to add user comment to custom action data: %ls", psu->wzComment); | 518 | ExitOnFailure(hr, "Failed to add user comment to custom action data: %ls", psu->wzComment); |
| 519 | 519 | ||
| 520 | // Check to see if the user already exists since we have to be very careful when adding | 520 | // Check to see if the user already exists since we have to be very careful when adding |
| 521 | // and removing users. Note: MSDN says that it is safe to call these APIs from any | 521 | // and removing users. |
| 522 | // user, so we should be safe calling it during immediate mode. | 522 | hr = GetDomainFromServerName(&pwzDomainName, psu->wzDomain, 0); |
| 523 | er = ::NetApiBufferAllocate(sizeof(USER_INFO_0), reinterpret_cast<LPVOID*>(&pUserInfo)); | 523 | ExitOnFailure(hr, "Failed to get domain from server name: %ls", psu->wzDomain); |
| 524 | hr = HRESULT_FROM_WIN32(er); | ||
| 525 | ExitOnFailure(hr, "Failed to allocate memory to check existence of user: %ls", psu->wzName); | ||
| 526 | |||
| 527 | LPCWSTR wzDomain = psu->wzDomain; | ||
| 528 | if (wzDomain && *wzDomain) | ||
| 529 | { | ||
| 530 | er = ::DsGetDcNameW(NULL, wzDomain, NULL, NULL, NULL, &pDomainControllerInfo); | ||
| 531 | if (RPC_S_SERVER_UNAVAILABLE == er) | ||
| 532 | { | ||
| 533 | // MSDN says, if we get the above error code, try again with the "DS_FORCE_REDISCOVERY" flag | ||
| 534 | er = ::DsGetDcNameW(NULL, wzDomain, NULL, NULL, DS_FORCE_REDISCOVERY, &pDomainControllerInfo); | ||
| 535 | } | ||
| 536 | if (ERROR_SUCCESS == er && pDomainControllerInfo->DomainControllerName) | ||
| 537 | { | ||
| 538 | // If the \\ prefix on the queried domain was present, skip it. | ||
| 539 | if ('\\' == *pDomainControllerInfo->DomainControllerName && '\\' == *pDomainControllerInfo->DomainControllerName + 1) | ||
| 540 | { | ||
| 541 | wzDomain = pDomainControllerInfo->DomainControllerName + 2; | ||
| 542 | } | ||
| 543 | else | ||
| 544 | { | ||
| 545 | wzDomain = pDomainControllerInfo->DomainControllerName; | ||
| 546 | } | ||
| 547 | } | ||
| 548 | } | ||
| 549 | 524 | ||
| 550 | er = ::NetUserGetInfo(wzDomain, psu->wzName, 0, reinterpret_cast<LPBYTE*>(pUserInfo)); | 525 | er = ::NetUserGetInfo(pwzDomainName, psu->wzName, 0, reinterpret_cast<LPBYTE*>(&pUserInfo)); |
| 551 | if (NERR_Success == er) | 526 | if (NERR_Success == er) |
| 552 | { | 527 | { |
| 553 | ueUserExists = USER_EXISTS_YES; | 528 | ueUserExists = USER_EXISTS_YES; |
| @@ -560,7 +535,7 @@ HRESULT ScaUserExecute( | |||
| 560 | { | 535 | { |
| 561 | ueUserExists = USER_EXISTS_INDETERMINATE; | 536 | ueUserExists = USER_EXISTS_INDETERMINATE; |
| 562 | hr = HRESULT_FROM_WIN32(er); | 537 | hr = HRESULT_FROM_WIN32(er); |
| 563 | WcaLog(LOGMSG_VERBOSE, "Failed to check existence of domain: %ls, user: %ls (error code 0x%x) - continuing", wzDomain, psu->wzName, hr); | 538 | WcaLog(LOGMSG_VERBOSE, "Failed to check existence of domain: %ls, user: %ls (error code 0x%x) - continuing", pwzDomainName, psu->wzName, hr); |
| 564 | hr = S_OK; | 539 | hr = S_OK; |
| 565 | er = ERROR_SUCCESS; | 540 | er = ERROR_SUCCESS; |
| 566 | } | 541 | } |
| @@ -685,11 +660,6 @@ HRESULT ScaUserExecute( | |||
| 685 | ::NetApiBufferFree(static_cast<LPVOID>(pUserInfo)); | 660 | ::NetApiBufferFree(static_cast<LPVOID>(pUserInfo)); |
| 686 | pUserInfo = NULL; | 661 | pUserInfo = NULL; |
| 687 | } | 662 | } |
| 688 | if (pDomainControllerInfo) | ||
| 689 | { | ||
| 690 | ::NetApiBufferFree(static_cast<LPVOID>(pDomainControllerInfo)); | ||
| 691 | pDomainControllerInfo = NULL; | ||
| 692 | } | ||
| 693 | } | 663 | } |
| 694 | 664 | ||
| 695 | LExit: | 665 | LExit: |
| @@ -697,14 +667,12 @@ LExit: | |||
| 697 | ReleaseStr(pwzScriptKey); | 667 | ReleaseStr(pwzScriptKey); |
| 698 | ReleaseStr(pwzActionData); | 668 | ReleaseStr(pwzActionData); |
| 699 | ReleaseStr(pwzRollbackData); | 669 | ReleaseStr(pwzRollbackData); |
| 670 | ReleaseStr(pwzDomainName); | ||
| 671 | |||
| 700 | if (pUserInfo) | 672 | if (pUserInfo) |
| 701 | { | 673 | { |
| 702 | ::NetApiBufferFree(static_cast<LPVOID>(pUserInfo)); | 674 | ::NetApiBufferFree(static_cast<LPVOID>(pUserInfo)); |
| 703 | } | 675 | } |
| 704 | if (pDomainControllerInfo) | ||
| 705 | { | ||
| 706 | ::NetApiBufferFree(static_cast<LPVOID>(pDomainControllerInfo)); | ||
| 707 | } | ||
| 708 | 676 | ||
| 709 | return hr; | 677 | return hr; |
| 710 | } | 678 | } |
diff --git a/src/ext/Util/ca/utilca.cpp b/src/ext/Util/ca/utilca.cpp index 37664a1c..d41f00c2 100644 --- a/src/ext/Util/ca/utilca.cpp +++ b/src/ext/Util/ca/utilca.cpp | |||
| @@ -1,3 +1,59 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. |
| 2 | 2 | ||
| 3 | #include "precomp.h" | 3 | #include "precomp.h" |
| 4 | |||
| 5 | HRESULT GetDomainFromServerName( | ||
| 6 | __deref_out_z LPWSTR* ppwzDomainName, | ||
| 7 | __in_z LPCWSTR wzServerName, | ||
| 8 | __in DWORD dwFlags | ||
| 9 | ) | ||
| 10 | { | ||
| 11 | HRESULT hr = S_OK; | ||
| 12 | DWORD er = ERROR_SUCCESS; | ||
| 13 | PDOMAIN_CONTROLLER_INFOW pDomainControllerInfo = NULL; | ||
| 14 | LPCWSTR wz = wzServerName ? wzServerName : L""; // initialize the domain to the provided server name (or empty string). | ||
| 15 | |||
| 16 | // If the server name was not empty, try to get the domain name out of it. | ||
| 17 | if (*wz) | ||
| 18 | { | ||
| 19 | er = ::DsGetDcNameW(NULL, wz, NULL, NULL, dwFlags, &pDomainControllerInfo); | ||
| 20 | if (RPC_S_SERVER_UNAVAILABLE == er) | ||
| 21 | { | ||
| 22 | // MSDN says, if we get the above error code, try again with the "DS_FORCE_REDISCOVERY" flag. | ||
| 23 | er = ::DsGetDcNameW(NULL, wz, NULL, NULL, dwFlags | DS_FORCE_REDISCOVERY, &pDomainControllerInfo); | ||
| 24 | } | ||
| 25 | ExitOnWin32Error(er, hr, "Could not get domain name from server name: %ls", wz); | ||
| 26 | |||
| 27 | if (pDomainControllerInfo->DomainControllerName) | ||
| 28 | { | ||
| 29 | // Skip the \\ prefix if present. | ||
| 30 | if ('\\' == *pDomainControllerInfo->DomainControllerName && '\\' == *(pDomainControllerInfo->DomainControllerName + 1)) | ||
| 31 | { | ||
| 32 | wz = pDomainControllerInfo->DomainControllerName + 2; | ||
| 33 | } | ||
| 34 | else | ||
| 35 | { | ||
| 36 | wz = pDomainControllerInfo->DomainControllerName; | ||
| 37 | } | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | LExit: | ||
| 42 | // Note: we overwrite the error code here as failure to contact domain controller above is not a fatal error. | ||
| 43 | if (wz && *wz) | ||
| 44 | { | ||
| 45 | hr = StrAllocString(ppwzDomainName, wz, 0); | ||
| 46 | } | ||
| 47 | else // return NULL the server name ended up empty. | ||
| 48 | { | ||
| 49 | ReleaseNullStr(*ppwzDomainName); | ||
| 50 | hr = S_OK; | ||
| 51 | } | ||
| 52 | |||
| 53 | if (pDomainControllerInfo) | ||
| 54 | { | ||
| 55 | ::NetApiBufferFree((LPVOID)pDomainControllerInfo); | ||
| 56 | } | ||
| 57 | |||
| 58 | return hr; | ||
| 59 | } | ||
diff --git a/src/ext/Util/ca/utilca.h b/src/ext/Util/ca/utilca.h new file mode 100644 index 00000000..97c54561 --- /dev/null +++ b/src/ext/Util/ca/utilca.h | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | #pragma once | ||
| 2 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 3 | |||
| 4 | HRESULT GetDomainFromServerName( | ||
| 5 | __deref_out_z LPWSTR* ppwzDomainName, | ||
| 6 | __in_z LPCWSTR wzServerName, | ||
| 7 | __in DWORD dwFlags | ||
| 8 | ); | ||
