diff options
-rw-r--r-- | src/ext/Util/ca/precomp.h | 1 | ||||
-rw-r--r-- | src/ext/Util/ca/scaexec.cpp | 6 | ||||
-rw-r--r-- | src/ext/Util/ca/scagroup.cpp | 17 | ||||
-rw-r--r-- | src/ext/Util/ca/scanet.cpp | 9 | ||||
-rw-r--r-- | src/ext/Util/ca/scanet.h | 14 | ||||
-rw-r--r-- | src/test/burn/WixTestTools/RuntimeFactAttribute.cs | 4 | ||||
-rw-r--r-- | src/test/msi/WixToolsetTest.MsiE2E/UtilExtensionGroupTests.cs | 6 |
7 files changed, 45 insertions, 12 deletions
diff --git a/src/ext/Util/ca/precomp.h b/src/ext/Util/ca/precomp.h index 9456c691..0d7cae18 100644 --- a/src/ext/Util/ca/precomp.h +++ b/src/ext/Util/ca/precomp.h | |||
@@ -51,5 +51,6 @@ | |||
51 | #include "scasmb.h" | 51 | #include "scasmb.h" |
52 | #include "scasmbexec.h" | 52 | #include "scasmbexec.h" |
53 | #include "utilca.h" | 53 | #include "utilca.h" |
54 | #include "scanet.h" | ||
54 | 55 | ||
55 | #include "..\..\caDecor.h" | 56 | #include "..\..\caDecor.h" |
diff --git a/src/ext/Util/ca/scaexec.cpp b/src/ext/Util/ca/scaexec.cpp index a2ecdaab..ee3c164f 100644 --- a/src/ext/Util/ca/scaexec.cpp +++ b/src/ext/Util/ca/scaexec.cpp | |||
@@ -716,7 +716,7 @@ static HRESULT RemoveGroupInternal( | |||
716 | // | 716 | // |
717 | if (!(SCAG_DONT_CREATE_GROUP & iAttributes)) | 717 | if (!(SCAG_DONT_CREATE_GROUP & iAttributes)) |
718 | { | 718 | { |
719 | hr = GetDomainFromServerName(&pwzServerName, wzDomain, DS_WRITABLE_REQUIRED); | 719 | hr = GetDomainServerName(wzDomain, &pwzServerName, DS_WRITABLE_REQUIRED); |
720 | 720 | ||
721 | NET_API_STATUS er = ::NetLocalGroupDel(pwzServerName, wzName); | 721 | NET_API_STATUS er = ::NetLocalGroupDel(pwzServerName, wzName); |
722 | hr = HRESULT_FROM_WIN32(er); | 722 | hr = HRESULT_FROM_WIN32(er); |
@@ -1284,7 +1284,7 @@ extern "C" UINT __stdcall CreateGroup( | |||
1284 | 1284 | ||
1285 | if (!(SCAG_DONT_CREATE_GROUP & iAttributes)) | 1285 | if (!(SCAG_DONT_CREATE_GROUP & iAttributes)) |
1286 | { | 1286 | { |
1287 | hr = GetDomainFromServerName(&pwzServerName, pwzDomain, DS_WRITABLE_REQUIRED); | 1287 | hr = GetDomainServerName(pwzDomain, &pwzServerName, DS_WRITABLE_REQUIRED); |
1288 | ExitOnFailure(hr, "failed to find writable server for domain %ls.", pwzDomain); | 1288 | ExitOnFailure(hr, "failed to find writable server for domain %ls.", pwzDomain); |
1289 | 1289 | ||
1290 | // Set the group's comment | 1290 | // Set the group's comment |
@@ -1680,7 +1680,7 @@ HRESULT AlterGroupMembership(BOOL fRemove, BOOL fIsRollback) | |||
1680 | } | 1680 | } |
1681 | 1681 | ||
1682 | 1682 | ||
1683 | hr = GetDomainFromServerName(&pwzServerName, pwzParentDomain, DS_WRITABLE_REQUIRED); | 1683 | hr = GetDomainServerName(pwzParentDomain, &pwzServerName, DS_WRITABLE_REQUIRED); |
1684 | ExitOnFailure(hr, "failed to obtain writable server for domain %ls", pwzParentDomain); | 1684 | ExitOnFailure(hr, "failed to obtain writable server for domain %ls", pwzParentDomain); |
1685 | 1685 | ||
1686 | if (*pwzChildDomain) | 1686 | if (*pwzChildDomain) |
diff --git a/src/ext/Util/ca/scagroup.cpp b/src/ext/Util/ca/scagroup.cpp index bab438ea..666100b0 100644 --- a/src/ext/Util/ca/scagroup.cpp +++ b/src/ext/Util/ca/scagroup.cpp | |||
@@ -1,7 +1,6 @@ | |||
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 | #include "scanet.h" | ||
5 | 4 | ||
6 | LPCWSTR vcsGroupQuery = L"SELECT `Group`, `Component_`, `Name`, `Domain` FROM `Wix4Group` WHERE `Group`=?"; | 5 | LPCWSTR vcsGroupQuery = L"SELECT `Group`, `Component_`, `Name`, `Domain` FROM `Wix4Group` WHERE `Group`=?"; |
7 | enum eGroupQuery { vgqGroup = 1, vgqComponent, vgqName, vgqDomain }; | 6 | enum eGroupQuery { vgqGroup = 1, vgqComponent, vgqName, vgqDomain }; |
@@ -458,7 +457,20 @@ HRESULT ScaGroupExecute( | |||
458 | // and removing groups. Note: MSDN says that it is safe to call these APIs from any | 457 | // and removing groups. Note: MSDN says that it is safe to call these APIs from any |
459 | // user, so we should be safe calling it during immediate mode. | 458 | // user, so we should be safe calling it during immediate mode. |
460 | 459 | ||
461 | hr = GetDomainServerName(psg->wzDomain, &pwzServerName); | 460 | hr = GetDomainServerName(psg->wzDomain, &pwzServerName, 0); |
461 | if (HRESULT_FROM_WIN32(ERROR_NO_SUCH_DOMAIN) == hr) | ||
462 | { | ||
463 | if (SCAG_NON_VITAL & psg->iAttributes) | ||
464 | { | ||
465 | WcaLog(LOGMSG_VERBOSE, "Domain does not exist for non-vital group: %ls\\%ls - continuing", psg->wzDomain, psg->wzName); | ||
466 | hr = S_OK; | ||
467 | goto ExitCurrentGroup; | ||
468 | } | ||
469 | else | ||
470 | { | ||
471 | ExitOnFailure(hr, "Domain does not exist for vital group: %ls\\%ls - aborting", psg->wzDomain, psg->wzName); | ||
472 | } | ||
473 | } | ||
462 | 474 | ||
463 | er = ::NetLocalGroupGetInfo(pwzServerName, psg->wzName, 0, reinterpret_cast<LPBYTE*>(&pGroupInfo)); | 475 | er = ::NetLocalGroupGetInfo(pwzServerName, psg->wzName, 0, reinterpret_cast<LPBYTE*>(&pGroupInfo)); |
464 | if (NERR_Success == er) | 476 | if (NERR_Success == er) |
@@ -597,6 +609,7 @@ HRESULT ScaGroupExecute( | |||
597 | ExitOnFailure(hr, "failed to schedule RemoveGroup"); | 609 | ExitOnFailure(hr, "failed to schedule RemoveGroup"); |
598 | } | 610 | } |
599 | 611 | ||
612 | ExitCurrentGroup: | ||
600 | ReleaseNullStr(pwzScriptKey); | 613 | ReleaseNullStr(pwzScriptKey); |
601 | ReleaseNullStr(pwzActionData); | 614 | ReleaseNullStr(pwzActionData); |
602 | ReleaseNullStr(pwzRollbackData); | 615 | ReleaseNullStr(pwzRollbackData); |
diff --git a/src/ext/Util/ca/scanet.cpp b/src/ext/Util/ca/scanet.cpp index a8ad0316..ad6c8b01 100644 --- a/src/ext/Util/ca/scanet.cpp +++ b/src/ext/Util/ca/scanet.cpp | |||
@@ -8,8 +8,13 @@ HRESULT GetDomainServerName(LPCWSTR pwzDomain, LPWSTR* ppwzServerName, ULONG fla | |||
8 | DWORD er = ERROR_SUCCESS; | 8 | DWORD er = ERROR_SUCCESS; |
9 | PDOMAIN_CONTROLLER_INFOW pDomainControllerInfo = NULL; | 9 | PDOMAIN_CONTROLLER_INFOW pDomainControllerInfo = NULL; |
10 | HRESULT hr = S_OK; | 10 | HRESULT hr = S_OK; |
11 | WCHAR pwzComputerName[MAX_COMPUTERNAME_LENGTH + 1]; | ||
12 | DWORD cchComputerName = countof(pwzComputerName); | ||
11 | 13 | ||
12 | if (pwzDomain && *pwzDomain) | 14 | hr = ::GetComputerNameW(pwzComputerName, &cchComputerName); |
15 | ExitOnFailure(hr, "failed to obtain computer name"); | ||
16 | |||
17 | if (pwzDomain && *pwzDomain && 0!=lstrcmpiW(pwzComputerName, pwzDomain) && 0!=lstrcmpiW(L".", pwzDomain)) | ||
13 | { | 18 | { |
14 | er = ::DsGetDcNameW(NULL, pwzDomain, NULL, NULL, flags, &pDomainControllerInfo); | 19 | er = ::DsGetDcNameW(NULL, pwzDomain, NULL, NULL, flags, &pDomainControllerInfo); |
15 | if (RPC_S_SERVER_UNAVAILABLE == er) | 20 | if (RPC_S_SERVER_UNAVAILABLE == er) |
@@ -21,7 +26,7 @@ HRESULT GetDomainServerName(LPCWSTR pwzDomain, LPWSTR* ppwzServerName, ULONG fla | |||
21 | if (ERROR_SUCCESS == er && pDomainControllerInfo->DomainControllerName) | 26 | if (ERROR_SUCCESS == er && pDomainControllerInfo->DomainControllerName) |
22 | { | 27 | { |
23 | // Skip the \\ prefix if present. | 28 | // Skip the \\ prefix if present. |
24 | if ('\\' == *pDomainControllerInfo->DomainControllerName && '\\' == *pDomainControllerInfo->DomainControllerName + 1) | 29 | if ('\\' == *pDomainControllerInfo->DomainControllerName && '\\' == *(pDomainControllerInfo->DomainControllerName + 1) ) |
25 | { | 30 | { |
26 | hr = StrAllocString(ppwzServerName, pDomainControllerInfo->DomainControllerName + 2, 0); | 31 | hr = StrAllocString(ppwzServerName, pDomainControllerInfo->DomainControllerName + 2, 0); |
27 | } | 32 | } |
diff --git a/src/ext/Util/ca/scanet.h b/src/ext/Util/ca/scanet.h index 1fee61f8..efe6a408 100644 --- a/src/ext/Util/ca/scanet.h +++ b/src/ext/Util/ca/scanet.h | |||
@@ -1,4 +1,16 @@ | |||
1 | #pragma once | 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. | 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 | 3 | ||
4 | HRESULT GetDomainServerName(LPCWSTR pwzDomain, LPWSTR* ppwzServerName, ULONG flags = 0); | 4 | |
5 | /** | ||
6 | * Locates a domain controller (server name) for a given input domain. | ||
7 | * Flags can be provided where required (as per those for DsGetDcName) for a specific server to be returned. | ||
8 | * NOTE: Where the domain provided is identical to the local machine, this function will return NULL, such that the | ||
9 | * result can be provided directly to NetUserAdd or similar functions. | ||
10 | * | ||
11 | * @param pwzDomain Pointer to the domain name to be queried | ||
12 | * @param ppwzServerName Pointer to the server name to be returned | ||
13 | * @param flags Flags to be used in the DsGetDcName call(s) | ||
14 | * @return HRESULT to indicate if an error was encountered | ||
15 | */ | ||
16 | HRESULT GetDomainServerName(LPCWSTR pwzDomain, LPWSTR* ppwzServerName, ULONG flags); | ||
diff --git a/src/test/burn/WixTestTools/RuntimeFactAttribute.cs b/src/test/burn/WixTestTools/RuntimeFactAttribute.cs index d7f56f70..2644a1cc 100644 --- a/src/test/burn/WixTestTools/RuntimeFactAttribute.cs +++ b/src/test/burn/WixTestTools/RuntimeFactAttribute.cs | |||
@@ -47,6 +47,8 @@ namespace WixTestTools | |||
47 | 47 | ||
48 | var domainTestsEnabledString = Environment.GetEnvironmentVariable(RequiredDomainEnvironmentVariableName); | 48 | var domainTestsEnabledString = Environment.GetEnvironmentVariable(RequiredDomainEnvironmentVariableName); |
49 | RuntimeDomainTestsEnabled = Boolean.TryParse(domainTestsEnabledString, out var domainTestsEnabled) && domainTestsEnabled; | 49 | RuntimeDomainTestsEnabled = Boolean.TryParse(domainTestsEnabledString, out var domainTestsEnabled) && domainTestsEnabled; |
50 | |||
51 | RunningOnWindowsServer = IsWindowsServer(); | ||
50 | } | 52 | } |
51 | 53 | ||
52 | public bool DomainRequired | 54 | public bool DomainRequired |
@@ -63,8 +65,6 @@ namespace WixTestTools | |||
63 | this.Skip = $"These tests require the test host to be running as a domain member ({(RunningInDomain ? "passed" : "failed")}). These tests affect both MACHINE AND DOMAIN state. To accept the consequences, set the {RequiredDomainEnvironmentVariableName} environment variable to true ({(RuntimeDomainTestsEnabled ? "passed" : "failed")})."; | 65 | this.Skip = $"These tests require the test host to be running as a domain member ({(RunningInDomain ? "passed" : "failed")}). These tests affect both MACHINE AND DOMAIN state. To accept the consequences, set the {RequiredDomainEnvironmentVariableName} environment variable to true ({(RuntimeDomainTestsEnabled ? "passed" : "failed")})."; |
64 | } | 66 | } |
65 | } | 67 | } |
66 | |||
67 | RunningOnWindowsServer = IsWindowsServer(); | ||
68 | } | 68 | } |
69 | 69 | ||
70 | private bool _RequireWindowsServer; | 70 | private bool _RequireWindowsServer; |
diff --git a/src/test/msi/WixToolsetTest.MsiE2E/UtilExtensionGroupTests.cs b/src/test/msi/WixToolsetTest.MsiE2E/UtilExtensionGroupTests.cs index cee357a6..e379047d 100644 --- a/src/test/msi/WixToolsetTest.MsiE2E/UtilExtensionGroupTests.cs +++ b/src/test/msi/WixToolsetTest.MsiE2E/UtilExtensionGroupTests.cs | |||
@@ -151,12 +151,14 @@ namespace WixToolsetTest.MsiE2E | |||
151 | [RuntimeFact] | 151 | [RuntimeFact] |
152 | public void FailsIfRestrictedDomain() | 152 | public void FailsIfRestrictedDomain() |
153 | { | 153 | { |
154 | var testDomain = "DOESNOTEXIST"; | ||
155 | var testGroup = "testName1"; | ||
154 | var productRestrictedDomain = this.CreatePackageInstaller("ProductRestrictedDomain"); | 156 | var productRestrictedDomain = this.CreatePackageInstaller("ProductRestrictedDomain"); |
155 | 157 | ||
156 | string logFile = productRestrictedDomain.InstallProduct(MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE, "TESTDOMAIN=DOESNOTEXIST"); | 158 | string logFile = productRestrictedDomain.InstallProduct(MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE, $"TESTDOMAIN={testDomain}"); |
157 | 159 | ||
158 | // Verify expected error message in the log file | 160 | // Verify expected error message in the log file |
159 | Assert.True(LogVerifier.MessageInLogFile(logFile, "CreateGroup: Error 0x8007054b: failed to find Domain DOESNOTEXIST.")); | 161 | Assert.True(LogVerifier.MessageInLogFile(logFile, $"ConfigureGroups: Error 0x8007054b: Domain does not exist for vital group: {testDomain}\\{testGroup} - aborting")); |
160 | } | 162 | } |
161 | 163 | ||
162 | // Verify that a group can be created with a group comment | 164 | // Verify that a group can be created with a group comment |