Since wmic has been recently deprecated and is absent on new
systems, replace setting DNS domain "old-style" with powershell.
Some changes to the service implementation:
- remove action parameter and hardcode Set-DnsClient since this is
the only used action
- remove support of multiple domains, since we only pass a single domain
(tuntap_options.domain)
Github: fixes OpenVPN/openvpn#642
Change-Id: Iff2f4ea677fe2d88659d7814dab0f792f5004fb3
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1183
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20250915062013.2555-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg32938.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
| ... | ... |
@@ -383,7 +383,7 @@ out: |
| 383 | 383 |
} |
| 384 | 384 |
|
| 385 | 385 |
static void |
| 386 |
-do_dns_domain_wmic(bool add, const struct tuntap *tt) |
|
| 386 |
+do_dns_domain_pwsh(bool add, const struct tuntap *tt) |
|
| 387 | 387 |
{
|
| 388 | 388 |
if (!tt->options.domain) |
| 389 | 389 |
{
|
| ... | ... |
@@ -391,9 +391,14 @@ do_dns_domain_wmic(bool add, const struct tuntap *tt) |
| 391 | 391 |
} |
| 392 | 392 |
|
| 393 | 393 |
struct argv argv = argv_new(); |
| 394 |
- argv_printf(&argv, "%s%s nicconfig where (InterfaceIndex=%ld) call SetDNSDomain '%s'", |
|
| 395 |
- get_win_sys_path(), WMIC_PATH_SUFFIX, tt->adapter_index, add ? tt->options.domain : ""); |
|
| 396 |
- exec_command("WMIC", &argv, 1, M_WARN);
|
|
| 394 |
+ argv_printf(&argv, |
|
| 395 |
+ "%s%s -NoProfile -NonInteractive -Command Set-DnsClient -InterfaceIndex %lu -ConnectionSpecificSuffix '%s'", |
|
| 396 |
+ get_win_sys_path(), |
|
| 397 |
+ POWERSHELL_PATH_SUFFIX, |
|
| 398 |
+ tt->adapter_index, |
|
| 399 |
+ add ? tt->options.domain : "" |
|
| 400 |
+ ); |
|
| 401 |
+ exec_command("PowerShell", &argv, 1, M_WARN);
|
|
| 397 | 402 |
|
| 398 | 403 |
argv_free(&argv); |
| 399 | 404 |
} |
| ... | ... |
@@ -1269,7 +1274,7 @@ do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu, |
| 1269 | 1269 |
|
| 1270 | 1270 |
if (!tt->did_ifconfig_setup) |
| 1271 | 1271 |
{
|
| 1272 |
- do_dns_domain_wmic(true, tt); |
|
| 1272 |
+ do_dns_domain_pwsh(true, tt); |
|
| 1273 | 1273 |
} |
| 1274 | 1274 |
} |
| 1275 | 1275 |
#else /* platforms we have no IPv6 code for */ |
| ... | ... |
@@ -1625,7 +1630,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, |
| 1625 | 1625 |
tt->adapter_netmask, NI_IP_NETMASK | NI_OPTIONS); |
| 1626 | 1626 |
} |
| 1627 | 1627 |
|
| 1628 |
- do_dns_domain_wmic(true, tt); |
|
| 1628 |
+ do_dns_domain_pwsh(true, tt); |
|
| 1629 | 1629 |
} |
| 1630 | 1630 |
|
| 1631 | 1631 |
|
| ... | ... |
@@ -7024,7 +7029,7 @@ close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) |
| 7024 | 7024 |
{
|
| 7025 | 7025 |
if (!tt->did_ifconfig_setup) |
| 7026 | 7026 |
{
|
| 7027 |
- do_dns_domain_wmic(false, tt); |
|
| 7027 |
+ do_dns_domain_pwsh(false, tt); |
|
| 7028 | 7028 |
} |
| 7029 | 7029 |
|
| 7030 | 7030 |
netsh_delete_address_dns(tt, true, &gc); |
| ... | ... |
@@ -7050,7 +7055,7 @@ close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx) |
| 7050 | 7050 |
} |
| 7051 | 7051 |
else |
| 7052 | 7052 |
{
|
| 7053 |
- do_dns_domain_wmic(false, tt); |
|
| 7053 |
+ do_dns_domain_pwsh(false, tt); |
|
| 7054 | 7054 |
|
| 7055 | 7055 |
if (tt->options.ip_win32_type == IPW32_SET_NETSH) |
| 7056 | 7056 |
{
|
| ... | ... |
@@ -38,7 +38,7 @@ |
| 38 | 38 |
#define WIN_ROUTE_PATH_SUFFIX "\\system32\\route.exe" |
| 39 | 39 |
#define WIN_IPCONFIG_PATH_SUFFIX "\\system32\\ipconfig.exe" |
| 40 | 40 |
#define WIN_NET_PATH_SUFFIX "\\system32\\net.exe" |
| 41 |
-#define WMIC_PATH_SUFFIX "\\system32\\wbem\\wmic.exe" |
|
| 41 |
+#define POWERSHELL_PATH_SUFFIX "\\system32\\WindowsPowerShell\\v1.0\\powershell.exe" |
|
| 42 | 42 |
|
| 43 | 43 |
/* |
| 44 | 44 |
* Win32-specific OpenVPN code, targeted at the mingw |
| ... | ... |
@@ -1150,45 +1150,31 @@ out: |
| 1150 | 1150 |
} |
| 1151 | 1151 |
|
| 1152 | 1152 |
/** |
| 1153 |
- * Run command: wmic nicconfig (InterfaceIndex=$if_index) call $action ($data) |
|
| 1153 |
+ * Run command: powershell -NoProfile -NonInteractive -Command Set-DnsClient -InterfaceIndex %ld -ConnectionSpecificSuffix '%s' |
|
| 1154 | 1154 |
* @param if_index "index of interface" |
| 1155 |
- * @param action e.g., "SetDNSDomain" |
|
| 1156 | 1155 |
* @param data data if required for action |
| 1157 | 1156 |
* - a single word for SetDNSDomain, empty or NULL to delete |
| 1158 |
- * - comma separated values for a list |
|
| 1159 | 1157 |
*/ |
| 1160 | 1158 |
static DWORD |
| 1161 |
-wmic_nicconfig_cmd(const wchar_t *action, const NET_IFINDEX if_index, |
|
| 1162 |
- const wchar_t *data) |
|
| 1159 |
+pwsh_setdns_cmd(const NET_IFINDEX if_index, const wchar_t *data) |
|
| 1163 | 1160 |
{
|
| 1164 | 1161 |
DWORD err = 0; |
| 1165 | 1162 |
wchar_t argv0[MAX_PATH]; |
| 1166 | 1163 |
wchar_t *cmdline = NULL; |
| 1167 | 1164 |
int timeout = 10000; /* in msec */ |
| 1168 | 1165 |
|
| 1169 |
- openvpn_swprintf(argv0, _countof(argv0), L"%ls\\%ls", get_win_sys_path(), L"wbem\\wmic.exe"); |
|
| 1166 |
+ openvpn_swprintf(argv0, _countof(argv0), L"%ls\\%ls", get_win_sys_path(), L"WindowsPowerShell\\v1.0\\powershell.exe"); |
|
| 1170 | 1167 |
|
| 1171 |
- const wchar_t *fmt; |
|
| 1172 |
- /* comma separated list must be enclosed in parenthesis */ |
|
| 1173 |
- if (data && wcschr(data, L',')) |
|
| 1174 |
- {
|
|
| 1175 |
- fmt = L"wmic nicconfig where (InterfaceIndex=%ld) call %ls (%ls)"; |
|
| 1176 |
- } |
|
| 1177 |
- else |
|
| 1178 |
- {
|
|
| 1179 |
- fmt = L"wmic nicconfig where (InterfaceIndex=%ld) call %ls \"%ls\""; |
|
| 1180 |
- } |
|
| 1168 |
+ const wchar_t *fmt = L"-NoProfile -NonInteractive -Command Set-DnsClient -InterfaceIndex %lu -ConnectionSpecificSuffix '%s'"; |
|
| 1181 | 1169 |
|
| 1182 |
- size_t ncmdline = wcslen(fmt) + 20 + wcslen(action) /* max 20 for ifindex */ |
|
| 1183 |
- + (data ? wcslen(data) + 1 : 1); |
|
| 1170 |
+ size_t ncmdline = wcslen(fmt) + 20 + /* max 20 for ifindex */ (data ? wcslen(data) + 1 : 1); |
|
| 1184 | 1171 |
cmdline = malloc(ncmdline*sizeof(wchar_t)); |
| 1185 | 1172 |
if (!cmdline) |
| 1186 | 1173 |
{
|
| 1187 | 1174 |
return ERROR_OUTOFMEMORY; |
| 1188 | 1175 |
} |
| 1189 | 1176 |
|
| 1190 |
- openvpn_swprintf(cmdline, ncmdline, fmt, if_index, action, |
|
| 1191 |
- data ? data : L""); |
|
| 1177 |
+ openvpn_swprintf(cmdline, ncmdline, fmt, if_index, data ? data : L""); |
|
| 1192 | 1178 |
err = ExecCommand(argv0, cmdline, timeout); |
| 1193 | 1179 |
|
| 1194 | 1180 |
free(cmdline); |
| ... | ... |
@@ -1248,7 +1234,7 @@ SetDNSDomain(const wchar_t *if_name, const char *domain, undo_lists_t *lists) |
| 1248 | 1248 |
free(RemoveListItem(&(*lists)[undo_domain], CmpWString, (void *)if_name)); |
| 1249 | 1249 |
} |
| 1250 | 1250 |
|
| 1251 |
- err = wmic_nicconfig_cmd(L"SetDNSDomain", if_index, wdomain); |
|
| 1251 |
+ err = pwsh_setdns_cmd(if_index, wdomain); |
|
| 1252 | 1252 |
|
| 1253 | 1253 |
/* Add to undo list if domain is non-empty */ |
| 1254 | 1254 |
if (err == 0 && wdomain[0] && lists) |