vmware-nsx/quantum/rootwrap/wrapper.py
Mark McClain 195a176337 add rootwrap filters to wrap ip netns exec
fixes bug 1044083

This patch adds specific filters for the ip command. The first filter
matches ip with any subcomand except netns exec.  The second filter
matches "ip netns exec" and then relies on the caller (match_filter) to
verify the sub-command against the other filters. Matching the
subcommand separately allows for a single set of filter definitions that
work with and without namespaces.

Change-Id: Ifd0378dc3461f84867efb3cb60396d9cfa9e582d
2012-09-04 22:25:34 -04:00

87 lines
3.0 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 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.
import ConfigParser
import os
import string
import sys
# this import has the effect of defining global var "filters",
# referenced by build_filter(), below. It gets set up by
# quantum-rootwrap, when we load_filters().
from quantum.rootwrap import filters
def build_filter(class_name, *args):
"""Returns a filter object of class class_name"""
if not hasattr(filters, class_name):
# TODO(jrd): Log the error (whenever quantum-rootwrap has a log file)
return None
filterclass = getattr(filters, class_name)
return filterclass(*args)
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(filter_list, userargs):
"""
Checks user command and arguments through command filters and
returns the first matching filter, or None is none matched.
"""
found_filter = None
for f in filter_list:
if f.match(userargs):
if isinstance(f, filters.ExecCommandFilter):
# This command calls exec verify that remaining args
# matches another filter.
leaf_filters = [fltr for fltr in filter_list
if not isinstance(fltr,
filters.ExecCommandFilter)]
args = f.exec_args(userargs)
if not args or not match_filter(leaf_filters, args):
continue
# Try other filters if executable is absent
if not os.access(f.exec_path, os.X_OK):
if not found_filter:
found_filter = f
continue
# Otherwise return matching filter for execution
return f
# No filter matched or first missing executable
return found_filter