File 0001-Fix-running-unknown-commands-in-daemon-mode.patch of Package python-oslo.rootwrap

From b3ab63448f6c5ae45ad11d63a6db355db67f7c93 Mon Sep 17 00:00:00 2001
From: Thomas Bechtold <thomasbechtold@jpberlin.de>
Date: Thu, 13 Oct 2016 08:32:08 +0200
Subject: [PATCH] Fix running unknown commands in daemon mode

Running a unknown command (which is mentioned in the filter
but not available on the filesystem) leads currently to an exception.
Make sure that the return codes for both, daemon and non-daemon mode
are equal when running the same command.
Also add functional tests for this case.

Change-Id: I20004c3c370d004b5b76f4c8f8ab167d0949fabf
Closes-Bug: #1632768
---
 oslo_rootwrap/daemon.py                | 28 ++++++++++++++++++++--------
 oslo_rootwrap/tests/test_functional.py | 14 ++++++++++----
 2 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/oslo_rootwrap/daemon.py b/oslo_rootwrap/daemon.py
index 5409dfd..3cda49a 100644
--- a/oslo_rootwrap/daemon.py
+++ b/oslo_rootwrap/daemon.py
@@ -27,6 +27,7 @@ import sys
 import tempfile
 import threading
 
+from oslo_rootwrap import cmd
 from oslo_rootwrap import jsonrpc
 from oslo_rootwrap import subprocess
 from oslo_rootwrap import wrapper
@@ -45,14 +46,25 @@ class RootwrapClass(object):
         self.filters = filters
 
     def run_one_command(self, userargs, stdin=None):
-        obj = wrapper.start_subprocess(
-            self.filters, userargs,
-            exec_dirs=self.config.exec_dirs,
-            log=self.config.use_syslog,
-            close_fds=True,
-            stdin=subprocess.PIPE,
-            stdout=subprocess.PIPE,
-            stderr=subprocess.PIPE)
+        try:
+            obj = wrapper.start_subprocess(
+                self.filters, userargs,
+                exec_dirs=self.config.exec_dirs,
+                log=self.config.use_syslog,
+                close_fds=True,
+                stdin=subprocess.PIPE,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.PIPE)
+        except wrapper.FilterMatchNotExecutable:
+            LOG.warn("Executable not found for: %s"
+                     % ' '.join(userargs))
+            return cmd.RC_NOEXECFOUND, "", ""
+
+        except wrapper.NoFilterMatched:
+            LOG.warn("Unauthorized command: %s (no filter matched)"
+                     % ' '.join(userargs))
+            return cmd.RC_UNAUTHORIZED, "", ""
+
         if six.PY3 and stdin is not None:
             stdin = os.fsencode(stdin)
         out, err = obj.communicate(stdin)
diff --git a/oslo_rootwrap/tests/test_functional.py b/oslo_rootwrap/tests/test_functional.py
index a23d9f1..83825a5 100644
--- a/oslo_rootwrap/tests/test_functional.py
+++ b/oslo_rootwrap/tests/test_functional.py
@@ -34,9 +34,9 @@ import testtools
 from testtools import content
 
 from oslo_rootwrap import client
+from oslo_rootwrap import cmd
 from oslo_rootwrap import subprocess
 from oslo_rootwrap.tests import run_daemon
-from oslo_rootwrap import wrapper
 
 
 class _FunctionalBase(object):
@@ -57,6 +57,7 @@ echo: CommandFilter, /bin/echo, root
 cat: CommandFilter, /bin/cat, root
 sh: CommandFilter, /bin/sh, root
 id: CommandFilter, /usr/bin/id, nobody
+unknown_cmd: CommandFilter, /unknown/unknown_cmd, root
 """)
 
     def _test_run_once(self, expect_byte=True):
@@ -83,6 +84,14 @@ id: CommandFilter, /usr/bin/id, nobody
         self.assertEqual(expect_out, out)
         self.assertEqual(expect_err, err)
 
+    def test_run_command_not_found(self):
+        code, out, err = self.execute(['unknown_cmd'])
+        self.assertEqual(cmd.RC_NOEXECFOUND, code)
+
+    def test_run_unauthorized_command(self):
+        code, out, err = self.execute(['unauthorized_cmd'])
+        self.assertEqual(cmd.RC_UNAUTHORIZED, code)
+
     def test_run_as(self):
         if os.getuid() != 0:
             self.skip('Test requires root (for setuid)')
@@ -183,9 +192,6 @@ class RootwrapDaemonTest(_FunctionalBase, testtools.TestCase):
     def test_run_with_stdin(self):
         self._test_run_with_stdin(expect_byte=False)
 
-    def test_error_propagation(self):
-        self.assertRaises(wrapper.NoFilterMatched, self.execute, ['other'])
-
     def test_daemon_ressurection(self):
         # Let the client start a daemon
         self.execute(['cat'])
-- 
2.10.1

openSUSE Build Service is sponsored by