Move rootwrap filters definition to config files
Move rootwrap filters definition from being defined within Nova code to being defined in configuration files to facilitate pluging-in new rootwrap commands. Transition notes: * nova-rootwrap now requires an additional (first) parameter pointing to the root-owned rootwrap.conf file, sudoers needs to be updated to specify that ("nova-rootwrap /etc/nova/rootwrap.conf *") * Packagers should ship {compute,network,volume}.filters inside a directory listed in rootwrap.conf rather than shipping nova/rootwrap/{compute,network,volume}.py * Filter definitions now only support strings. The KillFilter (which was using arrays as parameters) was modified and the tests updated. Implements bp nova-rootwrap-pluggable-filters Corresponding devstack change needs to land first, so that tests pass: https://review.openstack.org/8842 Change-Id: I2350154cd8057bd57926ed542de035626f7de37d
This commit is contained in:
parent
3252371afc
commit
93d3c77caf
@ -18,21 +18,21 @@
|
||||
|
||||
"""Root wrapper for Nova
|
||||
|
||||
Uses modules in nova.rootwrap containing filters for commands
|
||||
that nova is allowed to run as another user.
|
||||
Filters which commands nova is allowed to run as another user.
|
||||
|
||||
To switch to using this, you should:
|
||||
* Set "--root_helper=sudo nova-rootwrap" in nova.conf
|
||||
* Allow nova to run nova-rootwrap as root in nova_sudoers:
|
||||
nova ALL = (root) NOPASSWD: /usr/bin/nova-rootwrap
|
||||
(all other commands can be removed from this file)
|
||||
To use this, you should set the following in nova.conf:
|
||||
root_helper=sudo nova-rootwrap /etc/nova/rootwrap.conf
|
||||
|
||||
You also need to let the nova user run nova-rootwrap as root in sudoers:
|
||||
nova ALL = (root) NOPASSWD: /usr/bin/nova-rootwrap /etc/nova/rootwrap.conf *
|
||||
|
||||
To make allowed commands node-specific, your packaging should only
|
||||
install nova/rootwrap/{compute,network,volume}.py respectively on
|
||||
compute, network and volume nodes (i.e. nova-api nodes should not
|
||||
have any of those files installed).
|
||||
install {compute,network,volume}.filters respectively on compute, network
|
||||
and volume nodes (i.e. nova-api nodes should not have any of those files
|
||||
installed).
|
||||
"""
|
||||
|
||||
import ConfigParser
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
@ -40,16 +40,27 @@ import sys
|
||||
|
||||
RC_UNAUTHORIZED = 99
|
||||
RC_NOCOMMAND = 98
|
||||
RC_BADCONFIG = 97
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Split arguments, require at least a command
|
||||
execname = sys.argv.pop(0)
|
||||
if len(sys.argv) == 0:
|
||||
if len(sys.argv) < 2:
|
||||
print "%s: %s" % (execname, "No command specified")
|
||||
sys.exit(RC_NOCOMMAND)
|
||||
|
||||
configfile = sys.argv.pop(0)
|
||||
userargs = sys.argv[:]
|
||||
|
||||
# Load configuration
|
||||
config = ConfigParser.RawConfigParser()
|
||||
config.read(configfile)
|
||||
try:
|
||||
filters_path = config.get("DEFAULT", "filters_path").split(",")
|
||||
except ConfigParser.Error:
|
||||
print "%s: Incorrect configuration file: %s" % (execname, configfile)
|
||||
sys.exit(RC_BADCONFIG)
|
||||
|
||||
# Add ../ to sys.path to allow running from branch
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(execname),
|
||||
os.pardir, os.pardir))
|
||||
@ -59,7 +70,7 @@ if __name__ == '__main__':
|
||||
from nova.rootwrap import wrapper
|
||||
|
||||
# Execute command if it matches any of the loaded filters
|
||||
filters = wrapper.load_filters()
|
||||
filters = wrapper.load_filters(filters_path)
|
||||
filtermatch = wrapper.match_filter(filters, userargs)
|
||||
if filtermatch:
|
||||
obj = subprocess.Popen(filtermatch.get_command(userargs),
|
||||
|
7
etc/nova/rootwrap.conf
Normal file
7
etc/nova/rootwrap.conf
Normal file
@ -0,0 +1,7 @@
|
||||
# Configuration for nova-rootwrap
|
||||
# This file should be owned by (and only-writeable by) the root user
|
||||
|
||||
[DEFAULT]
|
||||
# List of directories to load filter definitions from (separated by ',').
|
||||
# These directories MUST all be only writeable by root !
|
||||
filters_path=/etc/nova/rootwrap.d,/usr/share/nova/rootwrap
|
187
etc/nova/rootwrap.d/compute.filters
Normal file
187
etc/nova/rootwrap.d/compute.filters
Normal file
@ -0,0 +1,187 @@
|
||||
# nova-rootwrap command filters for compute nodes
|
||||
# This file should be owned by (and only-writeable by) the root user
|
||||
|
||||
[Filters]
|
||||
# nova/virt/disk/mount.py: 'kpartx', '-a', device
|
||||
# nova/virt/disk/mount.py: 'kpartx', '-d', device
|
||||
kpartx: CommandFilter, /sbin/kpartx, root
|
||||
|
||||
# nova/virt/disk/mount.py: 'tune2fs', '-c', 0, '-i', 0, mapped_device
|
||||
# nova/virt/xenapi/vm_utils.py: tune2fs, -O ^has_journal, part_path
|
||||
# nova/virt/xenapi/vm_utils.py: tune2fs, -j, partition_path
|
||||
tune2fs: CommandFilter, /sbin/tune2fs, root
|
||||
|
||||
# nova/virt/disk/mount.py: 'mount', mapped_device, mount_dir
|
||||
# nova/virt/xenapi/vm_utils.py: 'mount', '-t', 'ext2,ext3,ext4,reiserfs'..
|
||||
mount: CommandFilter, /bin/mount, root
|
||||
|
||||
# nova/virt/disk/mount.py: 'umount', mapped_device
|
||||
# nova/virt/xenapi/vm_utils.py: 'umount', dev_path
|
||||
umount: CommandFilter, /bin/umount, root
|
||||
|
||||
# nova/virt/disk/nbd.py: 'qemu-nbd', '-c', device, image
|
||||
# nova/virt/disk/nbd.py: 'qemu-nbd', '-d', device
|
||||
qemu-nbd: CommandFilter, /usr/bin/qemu-nbd, root
|
||||
|
||||
# nova/virt/disk/loop.py: 'losetup', '--find', '--show', image
|
||||
# nova/virt/disk/loop.py: 'losetup', '--detach', device
|
||||
losetup: CommandFilter, /sbin/losetup, root
|
||||
|
||||
# nova/virt/disk/guestfs.py: 'guestmount', '--rw', '-a', image, '-i'
|
||||
# nova/virt/disk/guestfs.py: 'guestmount', '--rw', '-a', image, '-m' dev
|
||||
guestmount: CommandFilter, /usr/bin/guestmount, root
|
||||
|
||||
# nova/virt/disk/guestfs.py: 'fusermount', 'u', mount_dir
|
||||
fusermount: CommandFilter, /bin/fusermount, root
|
||||
fusermount_usr: CommandFilter, /usr/bin/fusermount, root
|
||||
|
||||
# nova/virt/disk/api.py: 'tee', metadata_path
|
||||
# nova/virt/disk/api.py: 'tee', '-a', keyfile
|
||||
# nova/virt/disk/api.py: 'tee', netfile
|
||||
tee: CommandFilter, /usr/bin/tee, root
|
||||
|
||||
# nova/virt/disk/api.py: 'mkdir', '-p', sshdir
|
||||
# nova/virt/disk/api.py: 'mkdir', '-p', netdir
|
||||
mkdir: CommandFilter, /bin/mkdir, root
|
||||
|
||||
# nova/virt/disk/api.py: 'chown', 'root', sshdir
|
||||
# nova/virt/disk/api.py: 'chown', 'root:root', netdir
|
||||
# nova/virt/libvirt/connection.py: 'chown', os.getuid( console_log
|
||||
# nova/virt/libvirt/connection.py: 'chown', os.getuid( console_log
|
||||
# nova/virt/libvirt/connection.py: 'chown', 'root', basepath('disk')
|
||||
# nova/utils.py: 'chown', owner_uid, path
|
||||
chown: CommandFilter, /bin/chown, root
|
||||
|
||||
# nova/virt/disk/api.py: 'chmod', '700', sshdir
|
||||
# nova/virt/disk/api.py: 'chmod', 755, netdir
|
||||
chmod: CommandFilter, /bin/chmod, root
|
||||
|
||||
# nova/virt/disk/api.py: 'cp', os.path.join(fs...
|
||||
cp: CommandFilter, /bin/cp, root
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap'
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'link', 'set', dev, 'up'
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'link', 'delete', dev
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev)
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1]
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge
|
||||
# nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ...
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, address,..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, address, ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up'
|
||||
ip: CommandFilter, /sbin/ip, root
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'tunctl', '-b', '-t', dev
|
||||
# nova/network/linux_net.py: 'tunctl', '-b', '-t', dev
|
||||
tunctl: CommandFilter, /bin/tunctl, root
|
||||
tunctl_usr: CommandFilter, /usr/sbin/tunctl, root
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'ovs-vsctl', ...
|
||||
# nova/virt/libvirt/vif.py: 'ovs-vsctl', 'del-port', ...
|
||||
# nova/network/linux_net.py: 'ovs-vsctl', ....
|
||||
ovs-vsctl: CommandFilter, /usr/bin/ovs-vsctl, root
|
||||
|
||||
# nova/network/linux_net.py: 'ovs-ofctl', ....
|
||||
ovs-ofctl: CommandFilter, /usr/bin/ovs-ofctl, root
|
||||
|
||||
# nova/virt/libvirt/connection.py: 'dd', if=%s % virsh_output, ...
|
||||
dd: CommandFilter, /bin/dd, root
|
||||
|
||||
# nova/virt/xenapi/volume_utils.py: 'iscsiadm', '-m', ...
|
||||
iscsiadm: CommandFilter, /sbin/iscsiadm, root
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: parted, --script, ...
|
||||
# nova/virt/xenapi/vm_utils.py: 'parted', '--script', dev_path, ..*.
|
||||
parted: CommandFilter, /sbin/parted, root
|
||||
parted_usr: CommandFilter, /usr/sbin/parted, root
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: fdisk %(dev_path)s
|
||||
fdisk: CommandFilter, /sbin/fdisk, root
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: e2fsck, -f, -p, partition_path
|
||||
e2fsck: CommandFilter, /sbin/e2fsck, root
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: resize2fs, partition_path
|
||||
resize2fs: CommandFilter, /sbin/resize2fs, root
|
||||
|
||||
# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ...
|
||||
iptables-save: CommandFilter, /sbin/iptables-save, root
|
||||
iptables-save_usr: CommandFilter, /usr/sbin/iptables-save, root
|
||||
ip6tables-save: CommandFilter, /sbin/ip6tables-save, root
|
||||
ip6tables-save_usr: CommandFilter, /usr/sbin/ip6tables-save, root
|
||||
|
||||
# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,)
|
||||
iptables-restore: CommandFilter, /sbin/iptables-restore, root
|
||||
iptables-restore_usr: CommandFilter, /usr/sbin/iptables-restore, root
|
||||
ip6tables-restore: CommandFilter, /sbin/ip6tables-restore, root
|
||||
ip6tables-restore_usr: CommandFilter, /usr/sbin/ip6tables-restore, root
|
||||
|
||||
# nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ...
|
||||
# nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],..
|
||||
arping: CommandFilter, /usr/bin/arping, root
|
||||
arping_sbin: CommandFilter, /sbin/arping, root
|
||||
|
||||
# nova/network/linux_net.py: 'route', '-n'
|
||||
# nova/network/linux_net.py: 'route', 'del', 'default', 'gw'
|
||||
# nova/network/linux_net.py: 'route', 'add', 'default', 'gw'
|
||||
# nova/network/linux_net.py: 'route', '-n'
|
||||
# nova/network/linux_net.py: 'route', 'del', 'default', 'gw', old_gw, ..
|
||||
# nova/network/linux_net.py: 'route', 'add', 'default', 'gw', old_gateway
|
||||
route: CommandFilter, /sbin/route, root
|
||||
|
||||
# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address
|
||||
dhcp_release: CommandFilter, /usr/bin/dhcp_release, root
|
||||
|
||||
# nova/network/linux_net.py: 'kill', '-9', pid
|
||||
# nova/network/linux_net.py: 'kill', '-HUP', pid
|
||||
kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP
|
||||
|
||||
# nova/network/linux_net.py: 'kill', pid
|
||||
kill_radvd: KillFilter, root, /usr/sbin/radvd
|
||||
|
||||
# nova/network/linux_net.py: dnsmasq call
|
||||
dnsmasq: DnsmasqFilter, /usr/sbin/dnsmasq, root
|
||||
|
||||
# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'..
|
||||
radvd: CommandFilter, /usr/sbin/radvd, root
|
||||
|
||||
# nova/network/linux_net.py: 'brctl', 'addbr', bridge
|
||||
# nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0
|
||||
# nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off'
|
||||
# nova/network/linux_net.py: 'brctl', 'addif', bridge, interface
|
||||
brctl: CommandFilter, /sbin/brctl, root
|
||||
brctl_usr: CommandFilter, /usr/sbin/brctl, root
|
||||
|
||||
# nova/virt/libvirt/utils.py: 'mkswap'
|
||||
# nova/virt/xenapi/vm_utils.py: 'mkswap'
|
||||
mkswap: CommandFilter, /sbin/mkswap, root
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: 'mkfs'
|
||||
mkfs: CommandFilter, /sbin/mkfs, root
|
||||
|
||||
# nova/virt/libvirt/utils.py: 'qemu-img'
|
||||
qemu-img: CommandFilter, /usr/bin/qemu-img, root
|
||||
|
||||
# nova/virt/disk/api.py: 'touch', target
|
||||
touch: CommandFilter, /usr/bin/touch, root
|
||||
|
||||
# nova/virt/libvirt/connection.py:
|
||||
read_initiator: ReadFileFilter, /etc/iscsi/initiatorname.iscsi
|
||||
|
||||
# nova/virt/libvirt/connection.py:
|
||||
lvremove: CommandFilter, /sbin/lvremove, root
|
||||
|
||||
# nova/virt/libvirt/utils.py:
|
||||
lvcreate: CommandFilter, /sbin/lvcreate, root
|
||||
|
||||
# nova/virt/libvirt/utils.py:
|
||||
vgs: CommandFilter, /sbin/vgs, root
|
83
etc/nova/rootwrap.d/network.filters
Normal file
83
etc/nova/rootwrap.d/network.filters
Normal file
@ -0,0 +1,83 @@
|
||||
# nova-rootwrap command filters for network nodes
|
||||
# This file should be owned by (and only-writeable by) the root user
|
||||
|
||||
[Filters]
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap'
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'link', 'set', dev, 'up'
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'link', 'delete', dev
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev)
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1]
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge
|
||||
# nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ...
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, address,..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, address, ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up'
|
||||
ip: CommandFilter, /sbin/ip, root
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'ovs-vsctl', ...
|
||||
# nova/virt/libvirt/vif.py: 'ovs-vsctl', 'del-port', ...
|
||||
# nova/network/linux_net.py: 'ovs-vsctl', ....
|
||||
ovs-vsctl: CommandFilter, /usr/bin/ovs-vsctl, root
|
||||
|
||||
# nova/network/linux_net.py: 'ovs-ofctl', ....
|
||||
ovs-ofctl: CommandFilter, /usr/bin/ovs-ofctl, root
|
||||
|
||||
# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ...
|
||||
iptables-save: CommandFilter, /sbin/iptables-save, root
|
||||
iptables-save_usr: CommandFilter, /usr/sbin/iptables-save, root
|
||||
ip6tables-save: CommandFilter, /sbin/ip6tables-save, root
|
||||
ip6tables-save_usr: CommandFilter, /usr/sbin/ip6tables-save, root
|
||||
|
||||
# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,)
|
||||
iptables-restore: CommandFilter, /sbin/iptables-restore, root
|
||||
iptables-restore_usr: CommandFilter, /usr/sbin/iptables-restore, root
|
||||
ip6tables-restore: CommandFilter, /sbin/ip6tables-restore, root
|
||||
ip6tables-restore_usr: CommandFilter, /usr/sbin/ip6tables-restore, root
|
||||
|
||||
# nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ...
|
||||
# nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],..
|
||||
arping: CommandFilter, /usr/bin/arping, root
|
||||
arping_sbin: CommandFilter, /sbin/arping, root
|
||||
|
||||
# nova/network/linux_net.py: 'route', '-n'
|
||||
# nova/network/linux_net.py: 'route', 'del', 'default', 'gw'
|
||||
# nova/network/linux_net.py: 'route', 'add', 'default', 'gw'
|
||||
# nova/network/linux_net.py: 'route', '-n'
|
||||
# nova/network/linux_net.py: 'route', 'del', 'default', 'gw', old_gw, ..
|
||||
# nova/network/linux_net.py: 'route', 'add', 'default', 'gw', old_gateway
|
||||
route: CommandFilter, /sbin/route, root
|
||||
|
||||
# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address
|
||||
dhcp_release: CommandFilter, /usr/bin/dhcp_release, root
|
||||
|
||||
# nova/network/linux_net.py: 'kill', '-9', pid
|
||||
# nova/network/linux_net.py: 'kill', '-HUP', pid
|
||||
kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP
|
||||
|
||||
# nova/network/linux_net.py: 'kill', pid
|
||||
kill_radvd: KillFilter, root, /usr/sbin/radvd
|
||||
|
||||
# nova/network/linux_net.py: dnsmasq call
|
||||
dnsmasq: DnsmasqFilter, /usr/sbin/dnsmasq, root
|
||||
|
||||
# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'..
|
||||
radvd: CommandFilter, /usr/sbin/radvd, root
|
||||
|
||||
# nova/network/linux_net.py: 'brctl', 'addbr', bridge
|
||||
# nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0
|
||||
# nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off'
|
||||
# nova/network/linux_net.py: 'brctl', 'addif', bridge, interface
|
||||
brctl: CommandFilter, /sbin/brctl, root
|
||||
brctl_usr: CommandFilter, /usr/sbin/brctl, root
|
||||
|
||||
# nova/network/linux_net.py: 'sysctl', ....
|
||||
sysctl: CommandFilter, /sbin/sysctl, root
|
27
etc/nova/rootwrap.d/volume.filters
Normal file
27
etc/nova/rootwrap.d/volume.filters
Normal file
@ -0,0 +1,27 @@
|
||||
# nova-rootwrap command filters for volume nodes
|
||||
# This file should be owned by (and only-writeable by) the root user
|
||||
|
||||
[Filters]
|
||||
# nova/volume/iscsi.py: iscsi_helper '--op' ...
|
||||
ietadm: CommandFilter, /usr/sbin/ietadm, root
|
||||
tgtadm: CommandFilter, /usr/sbin/tgtadm, root
|
||||
|
||||
# nova/volume/driver.py: 'vgs', '--noheadings', '-o', 'name'
|
||||
vgs: CommandFilter, /sbin/vgs, root
|
||||
|
||||
# nova/volume/driver.py: 'lvcreate', '-L', sizestr, '-n', volume_name,..
|
||||
# nova/volume/driver.py: 'lvcreate', '-L', ...
|
||||
lvcreate: CommandFilter, /sbin/lvcreate, root
|
||||
|
||||
# nova/volume/driver.py: 'dd', 'if=%s' % srcstr, 'of=%s' % deststr,...
|
||||
dd: CommandFilter, /bin/dd, root
|
||||
|
||||
# nova/volume/driver.py: 'lvremove', '-f', %s/%s % ...
|
||||
lvremove: CommandFilter, /sbin/lvremove, root
|
||||
|
||||
# nova/volume/driver.py: 'lvdisplay', '--noheading', '-C', '-o', 'Attr',..
|
||||
lvdisplay: CommandFilter, /sbin/lvdisplay, root
|
||||
|
||||
# nova/volume/driver.py: 'iscsiadm', '-m', 'discovery', '-t',...
|
||||
# nova/volume/driver.py: 'iscsiadm', '-m', 'node', '-T', ...
|
||||
iscsiadm: CommandFilter, /sbin/iscsiadm, root
|
@ -1,207 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (c) 2011 OpenStack, LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova.rootwrap import filters
|
||||
|
||||
|
||||
filterlist = [
|
||||
# nova/virt/disk/mount.py: 'kpartx', '-a', device
|
||||
# nova/virt/disk/mount.py: 'kpartx', '-d', device
|
||||
filters.CommandFilter("/sbin/kpartx", "root"),
|
||||
|
||||
# nova/virt/disk/mount.py: 'tune2fs', '-c', 0, '-i', 0, mapped_device
|
||||
# nova/virt/xenapi/vm_utils.py: "tune2fs", "-O ^has_journal", part_path
|
||||
# nova/virt/xenapi/vm_utils.py: "tune2fs", "-j", partition_path
|
||||
filters.CommandFilter("/sbin/tune2fs", "root"),
|
||||
|
||||
# nova/virt/disk/mount.py: 'mount', mapped_device, mount_dir
|
||||
# nova/virt/xenapi/vm_utils.py: 'mount', '-t', 'ext2,ext3,ext4,reiserfs'..
|
||||
filters.CommandFilter("/bin/mount", "root"),
|
||||
|
||||
# nova/virt/disk/mount.py: 'umount', mapped_device
|
||||
# nova/virt/xenapi/vm_utils.py: 'umount', dev_path
|
||||
filters.CommandFilter("/bin/umount", "root"),
|
||||
|
||||
# nova/virt/disk/nbd.py: 'qemu-nbd', '-c', device, image
|
||||
# nova/virt/disk/nbd.py: 'qemu-nbd', '-d', device
|
||||
filters.CommandFilter("/usr/bin/qemu-nbd", "root"),
|
||||
|
||||
# nova/virt/disk/loop.py: 'losetup', '--find', '--show', image
|
||||
# nova/virt/disk/loop.py: 'losetup', '--detach', device
|
||||
filters.CommandFilter("/sbin/losetup", "root"),
|
||||
|
||||
# nova/virt/disk/guestfs.py: 'guestmount', '--rw', '-a', image, '-i'
|
||||
# nova/virt/disk/guestfs.py: 'guestmount', '--rw', '-a', image, '-m' dev
|
||||
filters.CommandFilter("/usr/bin/guestmount", "root"),
|
||||
|
||||
# nova/virt/disk/guestfs.py: 'fusermount', 'u', mount_dir
|
||||
filters.CommandFilter("/bin/fusermount", "root"),
|
||||
filters.CommandFilter("/usr/bin/fusermount", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'tee', metadata_path
|
||||
# nova/virt/disk/api.py: 'tee', '-a', keyfile
|
||||
# nova/virt/disk/api.py: 'tee', netfile
|
||||
filters.CommandFilter("/usr/bin/tee", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'mkdir', '-p', sshdir
|
||||
# nova/virt/disk/api.py: 'mkdir', '-p', netdir
|
||||
filters.CommandFilter("/bin/mkdir", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'chown', 'root', sshdir
|
||||
# nova/virt/disk/api.py: 'chown', 'root:root', netdir
|
||||
# nova/virt/libvirt/connection.py: 'chown', os.getuid(), console_log
|
||||
# nova/virt/libvirt/connection.py: 'chown', os.getuid(), console_log
|
||||
# nova/virt/libvirt/connection.py: 'chown', 'root', basepath('disk')
|
||||
# nova/utils.py: 'chown', owner_uid, path
|
||||
filters.CommandFilter("/bin/chown", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'chmod', '700', sshdir
|
||||
# nova/virt/disk/api.py: 'chmod', 755, netdir
|
||||
filters.CommandFilter("/bin/chmod", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'cp', os.path.join(fs...
|
||||
filters.CommandFilter("/bin/cp", "root"),
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap'
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'link', 'set', dev, 'up'
|
||||
# nova/virt/libvirt/vif.py: 'ip', 'link', 'delete', dev
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev)
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1]
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge
|
||||
# nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ...
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, "address",..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, "address", ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up'
|
||||
filters.CommandFilter("/sbin/ip", "root"),
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'tunctl', '-b', '-t', dev
|
||||
# nova/network/linux_net.py: 'tunctl', '-b', '-t', dev
|
||||
filters.CommandFilter("/usr/sbin/tunctl", "root"),
|
||||
filters.CommandFilter("/bin/tunctl", "root"),
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'ovs-vsctl', ...
|
||||
# nova/virt/libvirt/vif.py: 'ovs-vsctl', 'del-port', ...
|
||||
# nova/network/linux_net.py: 'ovs-vsctl', ....
|
||||
filters.CommandFilter("/usr/bin/ovs-vsctl", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'ovs-ofctl', ....
|
||||
filters.CommandFilter("/usr/bin/ovs-ofctl", "root"),
|
||||
|
||||
# nova/virt/libvirt/connection.py: 'dd', "if=%s" % virsh_output, ...
|
||||
filters.CommandFilter("/bin/dd", "root"),
|
||||
|
||||
# nova/virt/xenapi/volume_utils.py: 'iscsiadm', '-m', ...
|
||||
filters.CommandFilter("/sbin/iscsiadm", "root"),
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: "parted", "--script", ...
|
||||
# nova/virt/xenapi/vm_utils.py: 'parted', '--script', dev_path, ..*.
|
||||
filters.CommandFilter("/sbin/parted", "root"),
|
||||
filters.CommandFilter("/usr/sbin/parted", "root"),
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: fdisk %(dev_path)s
|
||||
filters.CommandFilter("/sbin/fdisk", "root"),
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: "e2fsck", "-f", "-p", partition_path
|
||||
filters.CommandFilter("/sbin/e2fsck", "root"),
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: "resize2fs", partition_path
|
||||
filters.CommandFilter("/sbin/resize2fs", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd,), '-t', ...
|
||||
filters.CommandFilter("/sbin/iptables-save", "root"),
|
||||
filters.CommandFilter("/usr/sbin/iptables-save", "root"),
|
||||
filters.CommandFilter("/sbin/ip6tables-save", "root"),
|
||||
filters.CommandFilter("/usr/sbin/ip6tables-save", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,)
|
||||
filters.CommandFilter("/sbin/iptables-restore", "root"),
|
||||
filters.CommandFilter("/usr/sbin/iptables-restore", "root"),
|
||||
filters.CommandFilter("/sbin/ip6tables-restore", "root"),
|
||||
filters.CommandFilter("/usr/sbin/ip6tables-restore", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ...
|
||||
# nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],..
|
||||
filters.CommandFilter("/usr/bin/arping", "root"),
|
||||
filters.CommandFilter("/sbin/arping", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'route', '-n'
|
||||
# nova/network/linux_net.py: 'route', 'del', 'default', 'gw'
|
||||
# nova/network/linux_net.py: 'route', 'add', 'default', 'gw'
|
||||
# nova/network/linux_net.py: 'route', '-n'
|
||||
# nova/network/linux_net.py: 'route', 'del', 'default', 'gw', old_gw, ..
|
||||
# nova/network/linux_net.py: 'route', 'add', 'default', 'gw', old_gateway
|
||||
filters.CommandFilter("/sbin/route", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address
|
||||
filters.CommandFilter("/usr/bin/dhcp_release", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'kill', '-9', pid
|
||||
# nova/network/linux_net.py: 'kill', '-HUP', pid
|
||||
filters.KillFilter("/bin/kill", "root",
|
||||
['-9', '-HUP'], ['/usr/sbin/dnsmasq']),
|
||||
|
||||
# nova/network/linux_net.py: 'kill', pid
|
||||
filters.KillFilter("/bin/kill", "root", [''], ['/usr/sbin/radvd']),
|
||||
|
||||
# nova/network/linux_net.py: dnsmasq call
|
||||
filters.DnsmasqFilter("/usr/sbin/dnsmasq", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'),..
|
||||
filters.CommandFilter("/usr/sbin/radvd", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'brctl', 'addbr', bridge
|
||||
# nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0
|
||||
# nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off'
|
||||
# nova/network/linux_net.py: 'brctl', 'addif', bridge, interface
|
||||
filters.CommandFilter("/sbin/brctl", "root"),
|
||||
filters.CommandFilter("/usr/sbin/brctl", "root"),
|
||||
|
||||
# nova/virt/libvirt/utils.py: 'mkswap'
|
||||
# nova/virt/xenapi/vm_utils.py: 'mkswap'
|
||||
filters.CommandFilter("/sbin/mkswap", "root"),
|
||||
|
||||
# nova/virt/xenapi/vm_utils.py: 'mkfs'
|
||||
filters.CommandFilter("/sbin/mkfs", "root"),
|
||||
|
||||
# nova/virt/libvirt/utils.py: 'qemu-img'
|
||||
filters.CommandFilter("/usr/bin/qemu-img", "root"),
|
||||
|
||||
# nova/virt/disk/api.py: 'touch', target
|
||||
filters.CommandFilter("/usr/bin/touch", "root"),
|
||||
|
||||
# nova/virt/libvirt/connection.py:
|
||||
filters.ReadFileFilter("/etc/iscsi/initiatorname.iscsi"),
|
||||
|
||||
# nova/virt/libvirt/connection.py:
|
||||
filters.CommandFilter("/sbin/lvremove", "root"),
|
||||
|
||||
# nova/virt/libvirt/utils.py:
|
||||
filters.CommandFilter("/sbin/lvcreate", "root"),
|
||||
|
||||
# nova/virt/libvirt/utils.py:
|
||||
filters.CommandFilter("/sbin/vgs", "root")
|
||||
|
||||
]
|
@ -91,28 +91,33 @@ class DnsmasqFilter(CommandFilter):
|
||||
|
||||
class KillFilter(CommandFilter):
|
||||
"""Specific filter for the kill calls.
|
||||
1st argument is a list of accepted signals (emptystring means no signal)
|
||||
2nd argument is a list of accepted affected executables.
|
||||
1st argument is the user to run /bin/kill under
|
||||
2nd argument is the location of the affected executable
|
||||
Subsequent arguments list the accepted signals (if any)
|
||||
|
||||
This filter relies on /proc to accurately determine affected
|
||||
executable, so it will only work on procfs-capable systems (not OSX).
|
||||
"""
|
||||
|
||||
def __init__(self, *args):
|
||||
super(KillFilter, self).__init__("/bin/kill", *args)
|
||||
|
||||
def match(self, userargs):
|
||||
if userargs[0] != "kill":
|
||||
return False
|
||||
args = list(userargs)
|
||||
if len(args) == 3:
|
||||
# A specific signal is requested
|
||||
signal = args.pop(1)
|
||||
if signal not in self.args[0]:
|
||||
if signal not in self.args[1:]:
|
||||
# Requested signal not in accepted list
|
||||
return False
|
||||
else:
|
||||
if len(args) != 2:
|
||||
# Incorrect number of arguments
|
||||
return False
|
||||
if '' not in self.args[0]:
|
||||
# No signal, but list doesn't include empty string
|
||||
if len(self.args) > 1:
|
||||
# No signal requested, but filter requires specific signal
|
||||
return False
|
||||
try:
|
||||
command = os.readlink("/proc/%d/exe" % int(args[1]))
|
||||
@ -120,8 +125,8 @@ class KillFilter(CommandFilter):
|
||||
# the end if an executable is updated or deleted
|
||||
if command.endswith(" (deleted)"):
|
||||
command = command[:command.rindex(" ")]
|
||||
if command not in self.args[1]:
|
||||
# Affected executable not in accepted list
|
||||
if command != self.args[0]:
|
||||
# Affected executable does not match
|
||||
return False
|
||||
except (ValueError, OSError):
|
||||
# Incorrect PID
|
||||
|
@ -1,98 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (c) 2011 OpenStack, LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova.rootwrap import filters
|
||||
|
||||
|
||||
filterlist = [
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',..
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev)
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1]
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge
|
||||
# nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ...
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, "address",..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, "address", ..
|
||||
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up'
|
||||
# nova/network/linux_net.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap'
|
||||
filters.CommandFilter("/sbin/ip", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd,), '-t', ...
|
||||
filters.CommandFilter("/sbin/iptables-save", "root"),
|
||||
filters.CommandFilter("/usr/sbin/iptables-save", "root"),
|
||||
filters.CommandFilter("/sbin/ip6tables-save", "root"),
|
||||
filters.CommandFilter("/usr/sbin/ip6tables-save", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,)
|
||||
filters.CommandFilter("/sbin/iptables-restore", "root"),
|
||||
filters.CommandFilter("/usr/sbin/iptables-restore", "root"),
|
||||
filters.CommandFilter("/sbin/ip6tables-restore", "root"),
|
||||
filters.CommandFilter("/usr/sbin/ip6tables-restore", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ...
|
||||
# nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],..
|
||||
filters.CommandFilter("/usr/bin/arping", "root"),
|
||||
filters.CommandFilter("/sbin/arping", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'route', '-n'
|
||||
# nova/network/linux_net.py: 'route', 'del', 'default', 'gw'
|
||||
# nova/network/linux_net.py: 'route', 'add', 'default', 'gw'
|
||||
# nova/network/linux_net.py: 'route', '-n'
|
||||
# nova/network/linux_net.py: 'route', 'del', 'default', 'gw', old_gw, ..
|
||||
# nova/network/linux_net.py: 'route', 'add', 'default', 'gw', old_gateway
|
||||
filters.CommandFilter("/sbin/route", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address
|
||||
filters.CommandFilter("/usr/bin/dhcp_release", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'kill', '-9', pid
|
||||
# nova/network/linux_net.py: 'kill', '-HUP', pid
|
||||
filters.KillFilter("/bin/kill", "root",
|
||||
['-9', '-HUP'], ['/usr/sbin/dnsmasq']),
|
||||
|
||||
# nova/network/linux_net.py: 'kill', pid
|
||||
filters.KillFilter("/bin/kill", "root", [''], ['/usr/sbin/radvd']),
|
||||
|
||||
# nova/network/linux_net.py: dnsmasq call
|
||||
filters.DnsmasqFilter("/usr/sbin/dnsmasq", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'),..
|
||||
filters.CommandFilter("/usr/sbin/radvd", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'brctl', 'addbr', bridge
|
||||
# nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0
|
||||
# nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off'
|
||||
# nova/network/linux_net.py: 'brctl', 'addif', bridge, interface
|
||||
filters.CommandFilter("/sbin/brctl", "root"),
|
||||
filters.CommandFilter("/usr/sbin/brctl", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'ovs-vsctl', ....
|
||||
filters.CommandFilter("/usr/bin/ovs-vsctl", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'ovs-ofctl', ....
|
||||
filters.CommandFilter("/usr/bin/ovs-ofctl", "root"),
|
||||
|
||||
# nova/network/linux_net.py: 'sysctl', ....
|
||||
filters.CommandFilter("/sbin/sysctl", "root"),
|
||||
]
|
@ -1,45 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (c) 2011 OpenStack, LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova.rootwrap import filters
|
||||
|
||||
|
||||
filterlist = [
|
||||
# nova/volume/iscsi.py: iscsi_helper '--op' ...
|
||||
filters.CommandFilter("/usr/sbin/ietadm", "root"),
|
||||
filters.CommandFilter("/usr/sbin/tgtadm", "root"),
|
||||
|
||||
# nova/volume/driver.py: 'vgs', '--noheadings', '-o', 'name'
|
||||
filters.CommandFilter("/sbin/vgs", "root"),
|
||||
|
||||
# nova/volume/driver.py: 'lvcreate', '-L', sizestr, '-n', volume_name,..
|
||||
# nova/volume/driver.py: 'lvcreate', '-L', ...
|
||||
filters.CommandFilter("/sbin/lvcreate", "root"),
|
||||
|
||||
# nova/volume/driver.py: 'dd', 'if=%s' % srcstr, 'of=%s' % deststr,...
|
||||
filters.CommandFilter("/bin/dd", "root"),
|
||||
|
||||
# nova/volume/driver.py: 'lvremove', '-f', "%s/%s" % ...
|
||||
filters.CommandFilter("/sbin/lvremove", "root"),
|
||||
|
||||
# nova/volume/driver.py: 'lvdisplay', '--noheading', '-C', '-o', 'Attr',..
|
||||
filters.CommandFilter("/sbin/lvdisplay", "root"),
|
||||
|
||||
# nova/volume/driver.py: 'iscsiadm', '-m', 'discovery', '-t',...
|
||||
# nova/volume/driver.py: 'iscsiadm', '-m', 'node', '-T', ...
|
||||
filters.CommandFilter("/sbin/iscsiadm", "root"),
|
||||
]
|
@ -15,29 +15,39 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import ConfigParser
|
||||
import os
|
||||
import sys
|
||||
import string
|
||||
|
||||
from nova.rootwrap import filters
|
||||
|
||||
|
||||
FILTERS_MODULES = ['nova.rootwrap.compute',
|
||||
'nova.rootwrap.network',
|
||||
'nova.rootwrap.volume',
|
||||
]
|
||||
def build_filter(class_name, *args):
|
||||
"""Returns a filter object of class class_name"""
|
||||
if not hasattr(filters, class_name):
|
||||
# TODO(ttx): Log the error (whenever nova-rootwrap has a log file)
|
||||
return None
|
||||
filterclass = getattr(filters, class_name)
|
||||
return filterclass(*args)
|
||||
|
||||
|
||||
def load_filters():
|
||||
"""Load filters from modules present in nova.rootwrap."""
|
||||
filters = []
|
||||
for modulename in FILTERS_MODULES:
|
||||
try:
|
||||
__import__(modulename)
|
||||
module = sys.modules[modulename]
|
||||
filters = filters + module.filterlist
|
||||
except ImportError:
|
||||
# It's OK to have missing filters, since filter modules are
|
||||
# shipped with specific nodes rather than with python-nova
|
||||
pass
|
||||
return filters
|
||||
def load_filters(filters_path):
|
||||
"""Load filters from a list of directories"""
|
||||
filterlist = []
|
||||
for filterdir in filters_path:
|
||||
if not os.path.isdir(filterdir):
|
||||
continue
|
||||
for filterfile in os.listdir(filterdir):
|
||||
filterconfig = ConfigParser.RawConfigParser()
|
||||
filterconfig.read(os.path.join(filterdir, filterfile))
|
||||
for (name, value) in filterconfig.items("Filters"):
|
||||
filterdefinition = [string.strip(s) for s in value.split(',')]
|
||||
newfilter = build_filter(*filterdefinition)
|
||||
if newfilter is None:
|
||||
continue
|
||||
filterlist.append(newfilter)
|
||||
return filterlist
|
||||
|
||||
|
||||
def match_filter(filters, userargs):
|
||||
|
@ -67,35 +67,33 @@ class RootwrapTestCase(test.TestCase):
|
||||
"Test requires /proc filesystem (procfs)")
|
||||
def test_KillFilter(self):
|
||||
p = subprocess.Popen(["/bin/sleep", "5"])
|
||||
f = filters.KillFilter("/bin/kill", "root",
|
||||
["-ALRM"],
|
||||
["/bin/sleep", "/usr/bin/sleep"])
|
||||
usercmd = ['kill', '-9', p.pid]
|
||||
f = filters.KillFilter("root", "/bin/sleep", "-9", "-HUP")
|
||||
f2 = filters.KillFilter("root", "/usr/bin/sleep", "-9", "-HUP")
|
||||
usercmd = ['kill', '-ALRM', p.pid]
|
||||
# Incorrect signal should fail
|
||||
self.assertFalse(f.match(usercmd))
|
||||
self.assertFalse(f.match(usercmd) or f2.match(usercmd))
|
||||
usercmd = ['kill', p.pid]
|
||||
# Providing no signal should fail
|
||||
self.assertFalse(f.match(usercmd))
|
||||
self.assertFalse(f.match(usercmd) or f2.match(usercmd))
|
||||
# Providing matching signal should be allowed
|
||||
usercmd = ['kill', '-9', p.pid]
|
||||
self.assertTrue(f.match(usercmd) or f2.match(usercmd))
|
||||
|
||||
f = filters.KillFilter("/bin/kill", "root",
|
||||
["-9", ""],
|
||||
["/bin/sleep", "/usr/bin/sleep"])
|
||||
usercmd = ['kill', '-9', os.getpid()]
|
||||
f = filters.KillFilter("root", "/bin/sleep")
|
||||
f2 = filters.KillFilter("root", "/usr/bin/sleep")
|
||||
usercmd = ['kill', os.getpid()]
|
||||
# Our own PID does not match /bin/sleep, so it should fail
|
||||
self.assertFalse(f.match(usercmd))
|
||||
usercmd = ['kill', '-9', 999999]
|
||||
self.assertFalse(f.match(usercmd) or f2.match(usercmd))
|
||||
usercmd = ['kill', 999999]
|
||||
# Nonexistant PID should fail
|
||||
self.assertFalse(f.match(usercmd))
|
||||
self.assertFalse(f.match(usercmd) or f2.match(usercmd))
|
||||
usercmd = ['kill', p.pid]
|
||||
# Providing no signal should work
|
||||
self.assertTrue(f.match(usercmd))
|
||||
usercmd = ['kill', '-9', p.pid]
|
||||
# Providing -9 signal should work
|
||||
self.assertTrue(f.match(usercmd))
|
||||
|
||||
def test_KillFilter_no_raise(self):
|
||||
"""Makes sure ValueError from bug 926412 is gone"""
|
||||
f = filters.KillFilter("/bin/kill", "root", [""])
|
||||
f = filters.KillFilter("root", "")
|
||||
# Providing anything other than kill should be False
|
||||
usercmd = ['notkill', 999999]
|
||||
self.assertFalse(f.match(usercmd))
|
||||
@ -109,9 +107,7 @@ class RootwrapTestCase(test.TestCase):
|
||||
def fake_readlink(blah):
|
||||
return '/bin/commandddddd (deleted)'
|
||||
|
||||
f = filters.KillFilter("/bin/kill", "root",
|
||||
[""],
|
||||
["/bin/commandddddd"])
|
||||
f = filters.KillFilter("root", "/bin/commandddddd")
|
||||
usercmd = ['kill', 1234]
|
||||
# Providing no signal should work
|
||||
self.stubs.Set(os, 'readlink', fake_readlink)
|
||||
|
Loading…
x
Reference in New Issue
Block a user