diff --git a/qubesadmin/tests/vm/actions.py b/qubesadmin/tests/vm/actions.py index 570bd87b5..eff775f2e 100644 --- a/qubesadmin/tests/vm/actions.py +++ b/qubesadmin/tests/vm/actions.py @@ -93,6 +93,51 @@ def test_011_run_windows(self): ('test-vm', 'qubes.VMShell', b'some command& exit\n'), ]) + def test_012_run_linux_root(self): + self.app.expected_calls[ + ("test-vm", "admin.vm.feature.CheckWithTemplate", "os", None) + ] = b"2\x00QubesFeatureNotFoundError\x00\x00Feature 'os' not set\x00" + self.app.expected_calls[ + ( + "test-vm", + "admin.vm.feature.CheckWithTemplate", + "supported-rpc.qubes.VMRootExec", + None, + ) + ] = ( + b"2\x00QubesFeatureNotFoundError\x00\x00" + b"Feature 'supported-rpc.qubes.VMRootExec' not set\x00" + ) + self.vm.run("some command", user="root") + self.assertEqual( + self.app.service_calls, + [ + ("test-vm", "qubes.VMShell", {"user": "root"}), + ("test-vm", "qubes.VMShell", b"some command; exit\n"), + ], + ) + + def test_013_run_linux_root_vmrootshell(self): + self.app.expected_calls[ + ("test-vm", "admin.vm.feature.CheckWithTemplate", "os", None) + ] = b"2\x00QubesFeatureNotFoundError\x00\x00Feature 'os' not set\x00" + self.app.expected_calls[ + ( + "test-vm", + "admin.vm.feature.CheckWithTemplate", + "supported-rpc.qubes.VMRootExec", + None, + ) + ] = b"0\x001" + self.vm.run("some command", user="root") + self.assertEqual( + self.app.service_calls, + [ + ("test-vm", "qubes.VMRootShell", {}), + ("test-vm", "qubes.VMRootShell", b"some command; exit\n"), + ], + ) + def test_015_run_with_args_shell(self): self.app.expected_calls[ ('test-vm', 'admin.vm.feature.CheckWithTemplate', 'vmexec', diff --git a/qubesadmin/vm/__init__.py b/qubesadmin/vm/__init__.py index 5ac7f1adb..55943747e 100644 --- a/qubesadmin/vm/__init__.py +++ b/qubesadmin/vm/__init__.py @@ -364,13 +364,20 @@ def run(self, command, input=None, **kwargs): # pylint: disable=redefined-builtin try: service = "qubes.VMShell" - if kwargs.get("user", None) == "root": + # intentionally check for qubes.VMRootExec, as this is when + # qubes.VMRootShell got force-user='root' in its config + if kwargs.get( + "user", None + ) == "root" and self.features.check_with_template( + "supported-rpc.qubes.VMRootExec", False + ): + kwargs.pop("user") service = "qubes.VMRootShell" return self.run_service_for_stdio( service, input=self.prepare_input_for_vmshell(command, input), - **kwargs + **kwargs, ) except subprocess.CalledProcessError as e: e.cmd = command