diff --git a/etc/quantum/rootwrap.d/dhcp.filters b/etc/quantum/rootwrap.d/dhcp.filters index 09204ad0a1..66fce34bbc 100644 --- a/etc/quantum/rootwrap.d/dhcp.filters +++ b/etc/quantum/rootwrap.d/dhcp.filters @@ -9,7 +9,7 @@ [Filters] # dhcp-agent -ip_exec_dnsmasq: DnsmasqFilter, /sbin/ip, root +ip_exec_dnsmasq: DnsmasqNetnsFilter, /sbin/ip, root dnsmasq: DnsmasqFilter, /sbin/dnsmasq, root dnsmasq_usr: DnsmasqFilter, /usr/sbin/dnsmasq, root # dhcp-agent uses kill as well, that's handled by the generic KillFilter diff --git a/quantum/rootwrap/filters.py b/quantum/rootwrap/filters.py index 976598a6c9..2e0e12c9a3 100644 --- a/quantum/rootwrap/filters.py +++ b/quantum/rootwrap/filters.py @@ -81,23 +81,17 @@ class DnsmasqFilter(CommandFilter): return True return False - def is_ip_netns_cmd(self, argv): - if ((argv[0] == "ip") and - (argv[1] == "netns") and - (argv[2] == "exec")): + def is_dnsmasq_env_vars(self, argv): + if (argv[0].startswith("QUANTUM_RELAY_SOCKET_PATH=") and + argv[1].startswith("QUANTUM_NETWORK_ID=")): return True return False def match(self, userargs): """This matches the combination of the leading env - vars, plus either "dnsmasq" (for the case where we're - not using netns) or "ip" "netns" "exec" "dnsmasq" - (for the case where we are)""" - if ((userargs[0].startswith("QUANTUM_RELAY_SOCKET_PATH=") and - userargs[1].startswith("QUANTUM_NETWORK_ID=") and - (self.is_dnsmasq_cmd(userargs[2:]) or - (self.is_ip_netns_cmd(userargs[2:]) and - self.is_dnsmasq_cmd(userargs[6:]))))): + vars plus "dnsmasq" """ + if (self.is_dnsmasq_env_vars(userargs) and + self.is_dnsmasq_cmd(userargs[2:])): return True return False @@ -111,6 +105,26 @@ class DnsmasqFilter(CommandFilter): return env +class DnsmasqNetnsFilter(DnsmasqFilter): + """Specific filter for the dnsmasq call (which includes env)""" + + def is_ip_netns_cmd(self, argv): + if ((argv[0] == "ip") and + (argv[1] == "netns") and + (argv[2] == "exec")): + return True + return False + + def match(self, userargs): + """This matches the combination of the leading env + vars plus "ip" "netns" "exec" "dnsmasq" """ + if (self.is_dnsmasq_env_vars(userargs) and + self.is_ip_netns_cmd(userargs[2:]) and + self.is_dnsmasq_cmd(userargs[6:])): + return True + return False + + class KillFilter(CommandFilter): """Specific filter for the kill calls. 1st argument is the user to run /bin/kill under diff --git a/quantum/tests/unit/test_rootwrap.py b/quantum/tests/unit/test_rootwrap.py index 979ff20ca0..427c7da137 100644 --- a/quantum/tests/unit/test_rootwrap.py +++ b/quantum/tests/unit/test_rootwrap.py @@ -65,6 +65,17 @@ class RootwrapTestCase(unittest.TestCase): self.assertEqual(env.get('QUANTUM_RELAY_SOCKET_PATH'), 'A') self.assertEqual(env.get('QUANTUM_NETWORK_ID'), 'foobar') + def test_DnsmasqNetnsFilter(self): + usercmd = ['QUANTUM_RELAY_SOCKET_PATH=A', 'QUANTUM_NETWORK_ID=foobar', + 'ip', 'netns', 'exec', 'foo', 'dnsmasq', 'foo'] + f = filters.DnsmasqNetnsFilter("/sbin/ip", "root") + self.assertTrue(f.match(usercmd)) + self.assertEqual(f.get_command(usercmd), ['/sbin/ip', 'netns', 'exec', + 'foo', 'dnsmasq', 'foo']) + env = f.get_environment(usercmd) + self.assertEqual(env.get('QUANTUM_RELAY_SOCKET_PATH'), 'A') + self.assertEqual(env.get('QUANTUM_NETWORK_ID'), 'foobar') + def test_KillFilter(self): p = utils.subprocess_popen(["/bin/sleep", "5"]) f = filters.KillFilter("root", "/bin/sleep", "-9", "-HUP")