Skip to content

Commit

Permalink
Fix rootwrap filter for dnsmasq when no namespace is used
Browse files Browse the repository at this point in the history
Fixes bug 1055384

Change-Id: I98381299f28da0e4c443efd4c22ba551022e0288
  • Loading branch information
Gary Kotton committed Sep 24, 2012
1 parent 6ae8f0a commit 6194ab2
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 13 deletions.
2 changes: 1 addition & 1 deletion etc/quantum/rootwrap.d/dhcp.filters
Expand Up @@ -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
Expand Down
38 changes: 26 additions & 12 deletions quantum/rootwrap/filters.py
Expand Up @@ -81,23 +81,17 @@ def is_dnsmasq_cmd(self, argv):
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" <foo> "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

Expand All @@ -111,6 +105,26 @@ def get_environment(self, userargs):
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" <foo> "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
Expand Down
11 changes: 11 additions & 0 deletions quantum/tests/unit/test_rootwrap.py
Expand Up @@ -65,6 +65,17 @@ def test_DnsmasqFilter(self):
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")
Expand Down

0 comments on commit 6194ab2

Please sign in to comment.