summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
Diffstat (limited to 'nova')
-rwxr-xr-xnova/rootwrap/filters.py17
-rw-r--r--nova/tests/test_nova_rootwrap.py9
-rw-r--r--nova/tests/test_utils.py12
-rw-r--r--nova/utils.py9
4 files changed, 47 insertions, 0 deletions
diff --git a/nova/rootwrap/filters.py b/nova/rootwrap/filters.py
index d16fc9a57..faaeb11f7 100755
--- a/nova/rootwrap/filters.py
+++ b/nova/rootwrap/filters.py
@@ -123,3 +123,20 @@ class KillFilter(CommandFilter):
# Incorrect PID
return False
return True
+
+
+class ReadFileFilter(CommandFilter):
+ """Specific filter for the utils.read_file_as_root call"""
+
+ def __init__(self, file_path, *args):
+ self.file_path = file_path
+ super(ReadFileFilter, self).__init__("/bin/cat", "root", *args)
+
+ def match(self, userargs):
+ if userargs[0] != 'cat':
+ return False
+ if userargs[1] != self.file_path:
+ return False
+ if len(userargs) != 2:
+ return False
+ return True
diff --git a/nova/tests/test_nova_rootwrap.py b/nova/tests/test_nova_rootwrap.py
index 4dc476615..38cce3b35 100644
--- a/nova/tests/test_nova_rootwrap.py
+++ b/nova/tests/test_nova_rootwrap.py
@@ -93,6 +93,15 @@ class RootwrapTestCase(test.TestCase):
# Providing -9 signal should work
self.assertTrue(f.match(usercmd))
+ def test_ReadFileFilter(self):
+ goodfn = '/good/file.name'
+ f = filters.ReadFileFilter(goodfn)
+ usercmd = ['cat', '/bad/file']
+ self.assertFalse(f.match(['cat', '/bad/file']))
+ usercmd = ['cat', goodfn]
+ self.assertEqual(f.get_command(usercmd), ['/bin/cat', goodfn])
+ self.assertTrue(f.match(usercmd))
+
def test_skips(self):
# Check that all filters are skipped and that the last matches
usercmd = ["cat", "/"]
diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py
index 6c6e6fcd8..5da717bee 100644
--- a/nova/tests/test_utils.py
+++ b/nova/tests/test_utils.py
@@ -382,6 +382,18 @@ class GenericUtilsTestCase(test.TestCase):
self.assertTrue([c for c in password
if c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'])
+ def test_read_file_as_root(self):
+ def fake_execute(*args, **kwargs):
+ if args[1] == 'bad':
+ raise exception.ProcessExecutionError
+ return 'fakecontents', None
+
+ self.stubs.Set(utils, 'execute', fake_execute)
+ contents = utils.read_file_as_root('good')
+ self.assertEqual(contents, 'fakecontents')
+ self.assertRaises(exception.FileNotFound,
+ utils.read_file_as_root, 'bad')
+
class IsUUIDLikeTestCase(test.TestCase):
def assertUUIDLike(self, val, expected):
diff --git a/nova/utils.py b/nova/utils.py
index c93b48fc6..a98897d82 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -1413,3 +1413,12 @@ def generate_mac_address():
random.randint(0x00, 0xff),
random.randint(0x00, 0xff)]
return ':'.join(map(lambda x: "%02x" % x, mac))
+
+
+def read_file_as_root(file_path):
+ """Secure helper to read file as root."""
+ try:
+ out, _err = execute('cat', file_path, run_as_root=True)
+ return out
+ except exception.ProcessExecutionError:
+ raise exception.FileNotFound(file_path=file_path)