Use cmd /c with runas on Windows to allow compound commands

This commit is contained in:
twangboy 2024-09-20 10:57:48 -06:00 committed by Daniel Wozniak
parent c44e8e3a66
commit aeecd6b7b2
4 changed files with 50 additions and 5 deletions

2
changelog/44736.fixed.md Normal file
View file

@ -0,0 +1,2 @@
Commands on Windows are now prefixed with ``cmd /c`` so that compound
commands (commands separated by ``&&``) run properly when using ``runas``

View file

@ -187,8 +187,10 @@ def runas(cmdLine, username, password=None, cwd=None):
| win32process.CREATE_SUSPENDED
)
flags = win32con.STARTF_USESTDHANDLES
flags |= win32con.STARTF_USESHOWWINDOW
startup_info = salt.platform.win.STARTUPINFO(
dwFlags=win32con.STARTF_USESTDHANDLES,
dwFlags=flags,
hStdInput=stdin_read.handle,
hStdOutput=stdout_write.handle,
hStdError=stderr_write.handle,
@ -204,7 +206,7 @@ def runas(cmdLine, username, password=None, cwd=None):
int(user_token),
logonflags=1,
applicationname=None,
commandline=cmdLine,
commandline=f'cmd /c "{cmdLine}"',
currentdirectory=cwd,
creationflags=creationflags,
startupinfo=startup_info,
@ -286,8 +288,10 @@ def runas_unpriv(cmd, username, password, cwd=None):
dupin = salt.platform.win.DuplicateHandle(srchandle=stdin, inherit=True)
# Get startup info structure
flags = win32con.STARTF_USESTDHANDLES
flags |= win32con.STARTF_USESHOWWINDOW
startup_info = salt.platform.win.STARTUPINFO(
dwFlags=win32con.STARTF_USESTDHANDLES,
dwFlags=flags,
hStdInput=dupin,
hStdOutput=c2pwrite,
hStdError=errwrite,
@ -300,7 +304,7 @@ def runas_unpriv(cmd, username, password, cwd=None):
domain=domain,
password=password,
logonflags=salt.platform.win.LOGON_WITH_PROFILE,
commandline=cmd,
commandline=f'cmd /c "{cmd}"',
startupinfo=startup_info,
currentdirectory=cwd,
)

View file

@ -0,0 +1,38 @@
"""
Test the win_runas util
"""
import pytest
import salt.utils.win_runas as win_runas
pytestmark = [
pytest.mark.windows_whitelisted,
pytest.mark.skip_unless_on_windows,
]
@pytest.fixture
def user():
with pytest.helpers.create_account() as account:
yield account
def test_runas(user):
cmd = "hostname && echo foo"
result = win_runas.runas(
cmdLine=cmd,
username=user.username,
password=user.password,
)
assert "foo" in result["stdout"]
def test_runas_unpriv(user):
cmd = "hostname && echo foo"
result = win_runas.runas_unpriv(
cmd=cmd,
username=user.username,
password=user.password,
)
assert "foo" in result["stdout"]

View file

@ -332,8 +332,9 @@ class TestAccount:
if salt.utils.platform.is_windows():
log.debug("Configuring system account: %s", self)
ret = self.sminion.functions.user.update(
self.username, password_never_expires=True
self.username, expired=False, password_never_expires=True
)
assert ret is True
if salt.utils.platform.is_darwin() or salt.utils.platform.is_windows():
password = self.password
else: