diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/python/xen/util/dictio.py | 50 | ||||
| -rw-r--r-- | tools/python/xen/util/security.py | 98 | ||||
| -rw-r--r-- | tools/python/xen/xend/server/blkif.py | 12 | ||||
| -rw-r--r-- | tools/python/xen/xm/addlabel.py | 152 | ||||
| -rw-r--r-- | tools/python/xen/xm/create.py | 121 | ||||
| -rw-r--r-- | tools/python/xen/xm/dry-run.py | 56 | ||||
| -rw-r--r-- | tools/python/xen/xm/getlabel.py | 114 | ||||
| -rw-r--r-- | tools/python/xen/xm/main.py | 30 | ||||
| -rw-r--r-- | tools/python/xen/xm/resources.py | 56 | ||||
| -rw-r--r-- | tools/python/xen/xm/rmlabel.py | 118 |
10 files changed, 765 insertions, 42 deletions
diff --git a/tools/python/xen/util/dictio.py b/tools/python/xen/util/dictio.py new file mode 100644 index 0000000000..4fcebdb88a --- /dev/null +++ b/tools/python/xen/util/dictio.py @@ -0,0 +1,50 @@ +#=========================================================================== +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Bryan D. Payne <bdpayne@us.ibm.com> +#============================================================================ + + +def dict_read(dictname, filename): + """Loads <filename> and returns the dictionary named <dictname> from + the file. + """ + dict = {} + + # read in the config file + globs = {} + locs = {} + execfile(filename, globs, locs) + + for (k, v) in locs.items(): + if k == dictname: + dict = v + break + + return dict + +def dict_write(dict, dictname, filename): + """Writes <dict> to <filename> using the name <dictname>. If the file + contains any other data, it will be overwritten. + """ + prefix = dictname + " = {\n" + suffix = "}\n" + fd = open(filename, "wb") + fd.write(prefix) + for key in dict: + line = " '" + str(key) + "': " + str(dict[key]) + ",\n" + fd.write(line) + fd.write(suffix) + fd.close() diff --git a/tools/python/xen/util/security.py b/tools/python/xen/util/security.py index f778cbc1fe..015de985b1 100644 --- a/tools/python/xen/util/security.py +++ b/tools/python/xen/util/security.py @@ -14,6 +14,7 @@ #============================================================================ # Copyright (C) 2006 International Business Machines Corp. # Author: Reiner Sailer +# Author: Bryan D. Payne <bdpayne@us.ibm.com> #============================================================================ import commands @@ -23,9 +24,12 @@ import traceback import shutil from xen.lowlevel import acm from xen.xend import sxp +from xen.xend.XendLogging import log +from xen.util import dictio #global directories and tools for security management policy_dir_prefix = "/etc/xen/acm-security/policies" +res_label_filename = policy_dir_prefix + "/resource_labels" boot_filename = "/boot/grub/menu.lst" xensec_xml2bin = "/usr/sbin/xensec_xml2bin" xensec_tool = "/usr/sbin/xensec_tool" @@ -530,3 +534,97 @@ def list_labels(policy_name, condition): if label not in labels: labels.append(label) return labels + + +def get_res_label(resource): + """Returns resource label information (label, policy) if it exists. + Otherwise returns null label and policy. + """ + def default_res_label(): + ssidref = NULL_SSIDREF + if on(): + label = ssidref2label(ssidref) + else: + label = None + return (label, 'NULL') + + (label, policy) = default_res_label() + + # load the resource label file + res_label_cache = {} + try: + res_label_cache = dictio.dict_read("resources", res_label_filename) + except: + log.info("Resource label file not found.") + return default_res_label() + + # find the resource information + if res_label_cache.has_key(resource): + (policy, label) = res_label_cache[resource] + + return (label, policy) + + +def get_res_security_details(resource): + """Returns the (label, ssidref, policy) associated with a given + resource from the global resource label file. + """ + def default_security_details(): + ssidref = NULL_SSIDREF + if on(): + label = ssidref2label(ssidref) + else: + label = None + policy = active_policy + return (label, ssidref, policy) + + (label, ssidref, policy) = default_security_details() + + # find the entry associated with this resource + (label, policy) = get_res_label(resource) + if policy == 'NULL': + log.info("Resource label for "+resource+" not in file, using DEFAULT.") + return default_security_details() + + # is this resource label for the running policy? + if policy == active_policy: + ssidref = label2ssidref(label, policy, 'res') + else: + log.info("Resource label not for active policy, using DEFAULT.") + return default_security_details() + + return (label, ssidref, policy) + + +def res_security_check(resource, domain_label): + """Checks if the given resource can be used by the given domain + label. Returns 1 if the resource can be used, otherwise 0. + """ + rtnval = 1 + + # if security is on, ask the hypervisor for a decision + if on(): + (label, ssidref, policy) = get_res_security_details(resource) + domac = ['access_control'] + domac.append(['policy', active_policy]) + domac.append(['label', domain_label]) + domac.append(['type', 'dom']) + decision = get_decision(domac, ['ssidref', str(ssidref)]) + + # provide descriptive error messages + if decision == 'DENIED': + if label == ssidref2label(NULL_SSIDREF): + raise ACMError("Resource '"+resource+"' is not labeled") + rtnval = 0 + else: + raise ACMError("Permission denied for resource '"+resource+"' because label '"+label+"' is not allowed") + rtnval = 0 + + # security is off, make sure resource isn't labeled + else: + (label, policy) = get_res_label(resource) + if policy != 'NULL': + raise ACMError("Security is off, but '"+resource+"' is labeled") + rtnval = 0 + + return rtnval diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index 02cd4f26f7..986d065be9 100644 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -21,6 +21,7 @@ import re import string from xen.util import blkif +from xen.util import security from xen.xend import sxp from xen.xend.XendError import VmError @@ -40,15 +41,22 @@ class BlkifController(DevController): def getDeviceDetails(self, config): """@see DevController.getDeviceDetails""" + uname = sxp.child_value(config, 'uname') dev = sxp.child_value(config, 'dev') - (typ, params) = string.split(sxp.child_value(config, 'uname'), ':', 1) + (typ, params) = string.split(uname, ':', 1) back = { 'dev' : dev, 'type' : typ, 'params' : params, 'mode' : sxp.child_value(config, 'mode', 'r') - } + } + + if security.on(): + (label, ssidref, policy) = security.get_res_security_details(uname) + back.update({'acm_label' : label, + 'acm_ssidref': str(ssidref), + 'acm_policy' : policy}) if 'ioemu:' in dev: (dummy, dev1) = string.split(dev, ':', 1) diff --git a/tools/python/xen/xm/addlabel.py b/tools/python/xen/xm/addlabel.py index 57b0f79691..1831ec2f80 100644 --- a/tools/python/xen/xm/addlabel.py +++ b/tools/python/xen/xm/addlabel.py @@ -14,59 +14,139 @@ #============================================================================ # Copyright (C) 2006 International Business Machines Corp. # Author: Reiner Sailer <sailer@us.ibm.com> +# Author: Bryan D. Payne <bdpayne@us.ibm.com> #============================================================================ -"""Labeling a domain configuration file. +"""Labeling a domain configuration file or a resoruce. """ import sys, os +import string import traceback +from xen.util import dictio +from xen.util import security +def usage(): + print "\nUsage: xm addlabel <label> dom <configfile> [<policy>]" + print " xm addlabel <label> res <resource> [<policy>]\n" + print " This program adds an acm_label entry into the 'configfile'" + print " for a domain or to the global resource label file for a" + print " resource. It derives the policy from the running hypervisor" + print " if it is not given (optional parameter). If a label already" + print " exists for the given domain or resource, then addlabel fails.\n" + + +def validate_config_file(configfile): + """Performs a simple sanity check on the configuration file passed on + the command line. We basically just want to make sure that it's + not a domain image file so we check for a few configuration values + and then we are satisfied. Returned 1 on success, otherwise 0. + """ + # read in the config file + globs = {} + locs = {} + try: + execfile(configfile, globs, locs) + except: + print "Invalid configuration file." + return 0 -from xen.util.security import ACMError, err, active_policy, label2ssidref, on, access_control_re + # sanity check on the data from the file + count = 0 + required = ['kernel', 'memory', 'name'] + for (k, v) in locs.items(): + if k in required: + count += 1 + if count != 3: + print "Invalid configuration file." + return 0 + else: + return 1 -def usage(): - print "\nUsage: xm addlabel <configfile> <label> [<policy>]\n" - print " This program adds an acm_label entry into the 'configfile'." - print " It derives the policy from the running hypervisor if it" - print " is not given (optional parameter). If the configfile is" - print " already labeled, then addlabel fails.\n" - err("Usage") +def add_resource_label(label, resource, policyref): + """Adds a resource label to the global resource label file. + """ + # sanity check: make sure this label can be instantiated later on + ssidref = security.label2ssidref(label, policyref, 'res') + + # sanity check on resource name + (type, file) = resource.split(":") + if type == "phy": + file = "/dev/" + file + if not os.path.exists(file): + print "Invalid resource '"+resource+"'" + return + + # see if this resource is already in the file + access_control = {} + file = security.res_label_filename + try: + access_control = dictio.dict_read("resources", file) + except: + print "Resource file not found, creating new file at:" + print "%s" % (file) + + if access_control.has_key(resource): + security.err("This resource is already labeled.") + # write the data to file + new_entry = { resource : tuple([policyref, label]) } + access_control.update(new_entry) + dictio.dict_write(access_control, "resources", file) -def main(argv): + +def add_domain_label(label, configfile, policyref): + # sanity checks: make sure this label can be instantiated later on + ssidref = security.label2ssidref(label, policyref, 'dom') + + new_label = "access_control = ['policy=%s,label=%s']\n" % (policyref, label) + if not os.path.isfile(configfile): + security.err("Configuration file \'" + configfile + "\' not found.") + config_fd = open(configfile, "ra+") + for line in config_fd: + if not security.access_control_re.match(line): + continue + config_fd.close() + security.err("Config file \'" + configfile + "\' is already labeled.") + config_fd.write(new_label) + config_fd.close() + + +def main (argv): try: policyref = None - if len(argv) not in [3,4]: + if len(argv) not in [4,5]: usage() - configfile = argv[1] - label = argv[2] + return + + label = argv[1] - if len(argv) == 4: - policyref = argv[3] - elif on(): - policyref = active_policy + if len(argv) == 5: + policyref = argv[4] + elif security.on(): + policyref = security.active_policy else: - err("No active policy. Policy must be specified in command line.") - - #sanity checks: make sure this label can be instantiated later on - ssidref = label2ssidref(label, policyref, 'dom') - - new_label = "access_control = ['policy=%s,label=%s']\n" % (policyref, label) - if not os.path.isfile(configfile): - err("Configuration file \'" + configfile + "\' not found.") - config_fd = open(configfile, "ra+") - for line in config_fd: - if not access_control_re.match(line): - continue - config_fd.close() - err("Config file \'" + configfile + "\' is already labeled.") - config_fd.write(new_label) - config_fd.close() + security.err("No active policy. Policy must be specified in command line.") - except ACMError: - pass - except: + if argv[2].lower() == "dom": + configfile = argv[3] + if configfile[0] != '/': + for prefix in [".", "/etc/xen"]: + configfile = prefix + "/" + configfile + if os.path.isfile(configfile): + fd = open(configfile, "rb") + break + if not validate_config_file(configfile): + usage() + else: + add_domain_label(label, configfile, policyref) + elif argv[2].lower() == "res": + resource = argv[3] + add_resource_label(label, resource, policyref) + else: + usage() + + except security.ACMError: traceback.print_exc(limit=1) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 5b9137510a..b9c775e5dc 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -25,6 +25,7 @@ import sys import socket import re import xmlrpclib +import traceback from xen.xend import sxp from xen.xend import PrettyPrint @@ -985,6 +986,117 @@ def parseCommandLine(argv): return (gopts, config) +def check_domain_label(config, verbose): + """All that we need to check here is that the domain label exists and + is not null when security is on. Other error conditions are + handled when the config file is parsed. + """ + answer = 0 + default_label = None + secon = 0 + if security.on(): + default_label = security.ssidref2label(security.NULL_SSIDREF) + secon = 1 + + # get the domain acm_label + dom_label = None + dom_name = None + for x in sxp.children(config): + if sxp.name(x) == 'security': + dom_label = sxp.child_value(sxp.name(sxp.child0(x)), 'label') + if sxp.name(x) == 'name': + dom_name = sxp.child0(x) + + # sanity check on domain label + if verbose: + print "Checking domain:" + if (not secon) and (not dom_label): + answer = 1 + if verbose: + print " %s: PERMITTED" % (dom_name) + elif (secon) and (dom_label) and (dom_label != default_label): + answer = 1 + if verbose: + print " %s: PERMITTED" % (dom_name) + else: + print " %s: DENIED" % (dom_name) + if not secon: + print " --> Security off, but domain labeled" + else: + print " --> Domain not labeled" + answer = 0 + + return answer + + +def config_security_check(config, verbose): + """Checks each resource listed in the config to see if the active + policy will permit creation of a new domain using the config. + Returns 1 if the config passes all tests, otherwise 0. + """ + answer = 1 + + # get the domain acm_label + domain_label = None + domain_policy = None + for x in sxp.children(config): + if sxp.name(x) == 'security': + domain_label = sxp.child_value(sxp.name(sxp.child0(x)), 'label') + domain_policy = sxp.child_value(sxp.name(sxp.child0(x)), 'policy') + + # if no domain label, use default + if not domain_label and security.on(): + try: + domain_label = security.ssidref2label(security.NULL_SSIDREF) + except: + traceback.print_exc(limit=1) + return 0 + domain_policy = 'NULL' + elif not domain_label: + domain_label = "" + domain_policy = 'NULL' + + if verbose: + print "Checking resources:" + + # build a list of all resources in the config file + resources = [] + for x in sxp.children(config): + if sxp.name(x) == 'device': + if sxp.name(sxp.child0(x)) == 'vbd': + resources.append(sxp.child_value(sxp.child0(x), 'uname')) + + # perform a security check on each resource + for resource in resources: + try: + security.res_security_check(resource, domain_label) + if verbose: + print " %s: PERMITTED" % (resource) + + except security.ACMError: + print " %s: DENIED" % (resource) + (res_label, res_policy) = security.get_res_label(resource) + print " --> res:"+res_label+" ("+res_policy+")" + print " --> dom:"+domain_label+" ("+domain_policy+")" + answer = 0 + + return answer + + +def create_security_check(config): + passed = 0 + try: + if check_domain_label(config, verbose=0): + if config_security_check(config, verbose=0): + passed = 1 + else: + print "Checking resources: (skipped)" + except security.ACMError: + traceback.print_exc(limit=1) + + return passed + + def main(argv): try: (opts, config) = parseCommandLine(argv) @@ -997,9 +1109,12 @@ def main(argv): if opts.vals.dryrun: PrettyPrint.prettyprint(config) else: - dom = make_domain(opts, config) - if opts.vals.console_autoconnect: - console.execConsole(dom) + if not create_security_check(config): + print "Security configuration prevents domain from starting" + else: + dom = make_domain(opts, config) + if opts.vals.console_autoconnect: + console.execConsole(dom) if __name__ == '__main__': main(sys.argv) diff --git a/tools/python/xen/xm/dry-run.py b/tools/python/xen/xm/dry-run.py new file mode 100644 index 0000000000..4290528636 --- /dev/null +++ b/tools/python/xen/xm/dry-run.py @@ -0,0 +1,56 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Bryan D. Payne <bdpayne@us.ibm.com> +#============================================================================ + +"""Tests the security settings for a domain and its resources. +""" +from xen.util import security +from xen.xm import create +from xen.xend import sxp + +def usage(): + print "\nUsage: xm dry-run <configfile>\n" + print "This program checks each resource listed in the configfile" + print "to see if the domain created by the configfile can access" + print "the resources. The status of each resource is listed" + print "individually along with the final security decision.\n" + + +def main (argv): + if len(argv) != 2: + usage() + return + + try: + passed = 0 + (opts, config) = create.parseCommandLine(argv) + if create.check_domain_label(config, verbose=1): + if create.config_security_check(config, verbose=1): + passed = 1 + else: + print "Checking resources: (skipped)" + + if passed: + print "Dry Run: PASSED" + else: + print "Dry Run: FAILED" + except security.ACMError: + pass + + +if __name__ == '__main__': + main(sys.argv) diff --git a/tools/python/xen/xm/getlabel.py b/tools/python/xen/xm/getlabel.py new file mode 100644 index 0000000000..c74e29f7a2 --- /dev/null +++ b/tools/python/xen/xm/getlabel.py @@ -0,0 +1,114 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Bryan D. Payne <bdpayne@us.ibm.com> +#============================================================================ + +"""Show the label for a domain or resoruce. +""" +import sys, os, re +import string +import traceback +from xen.util import dictio +from xen.util import security + +def usage(): + print "\nUsage: xm getlabel dom <configfile>" + print " xm getlabel res <resource>\n" + print " This program shows the label for a domain or resource.\n" + + +def get_resource_label(resource): + """Gets the resource label + """ + # read in the resource file + file = security.res_label_filename + try: + access_control = dictio.dict_read("resources", file) + except: + print "Resource label file not found" + return + + # get the entry and print label + if access_control.has_key(resource): + policy = access_control[resource][0] + label = access_control[resource][1] + print "policy="+policy+",label="+label + else: + print "Resource not labeled" + + +def get_domain_label(configfile): + # open the domain config file + fd = None + file = None + if configfile[0] == '/': + fd = open(configfile, "rb") + else: + for prefix in [".", "/etc/xen"]: + file = prefix + "/" + configfile + if os.path.isfile(file): + fd = open(file, "rb") + break + if not fd: + print "Configuration file '"+configfile+"' not found." + return + + # read in the domain config file, finding the label line + ac_entry_re = re.compile("^access_control\s*=.*", re.IGNORECASE) + ac_exit_re = re.compile(".*'\].*") + acline = "" + record = 0 + for line in fd.readlines(): + if ac_entry_re.match(line): + record = 1 + if record: + acline = acline + line + if record and ac_exit_re.match(line): + record = 0 + fd.close() + + # send error message if we didn't find anything + if acline == "": + print "Label does not exist in domain configuration file." + return + + # print out the label + (title, data) = acline.split("=", 1) + data = data.strip() + data = data.lstrip("[\'") + data = data.rstrip("\']") + print data + + +def main (argv): + if len(argv) != 3: + usage() + return + + if argv[1].lower() == "dom": + configfile = argv[2] + get_domain_label(configfile) + elif argv[1].lower() == "res": + resource = argv[2] + get_resource_label(resource) + else: + usage() + + +if __name__ == '__main__': + main(sys.argv) + + diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index d13e96eebf..791c18eacd 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -30,6 +30,7 @@ import socket import warnings warnings.filterwarnings('ignore', category=FutureWarning) import xmlrpclib +import traceback import xen.xend.XendProtocol @@ -119,7 +120,11 @@ vnet_list_help = "vnet-list [-l|--long] list vnets" vnet_create_help = "vnet-create <config> create a vnet from a config file" vnet_delete_help = "vnet-delete <vnetid> delete a vnet" vtpm_list_help = "vtpm-list <DomId> [--long] list virtual TPM devices" -addlabel_help = "addlabel <ConfigFile> <label> Add security label to ConfigFile" +addlabel_help = "addlabel <label> dom <configfile> Add security label to domain\n <label> res <resource> or resource" +rmlabel_help = "rmlabel dom <configfile> Remove security label from domain\n res <resource> or resource" +getlabel_help = "getlabel dom <configfile> Show security label for domain\n res <resource> or resource" +dry_run_help = "dry-run <configfile> Tests if domain can access its resources" +resources_help = "resources Show info for each labeled resource" cfgbootpolicy_help = "cfgbootpolicy <policy> Add policy to boot configuration " dumppolicy_help = "dumppolicy Print hypervisor ACM state information" loadpolicy_help = "loadpolicy <policy> Load binary policy into hypervisor" @@ -203,6 +208,10 @@ vnet_commands = [ acm_commands = [ "labels", "addlabel", + "rmlabel", + "getlabel", + "dry-run", + "resources", "makepolicy", "loadpolicy", "cfgbootpolicy", @@ -992,6 +1001,21 @@ def xm_block_attach(args): if len(args) == 5: vbd.append(['backend', args[4]]) + # verify that policy permits attaching this resource + try: + if security.on(): + dominfo = server.xend.domain(dom) + label = security.get_security_printlabel(dominfo) + else: + label = None + security.res_security_check(args[1], label) + except security.ACMError, e: + print e.value + sys.exit(1) + except: + traceback.print_exc(limit=1) + sys.exit(1) + server.xend.domain.device_create(dom, vbd) @@ -1124,6 +1148,10 @@ subcommands = [ 'shutdown', 'labels', 'addlabel', + 'rmlabel', + 'getlabel', + 'dry-run', + 'resources', 'cfgbootpolicy', 'makepolicy', 'loadpolicy', diff --git a/tools/python/xen/xm/resources.py b/tools/python/xen/xm/resources.py new file mode 100644 index 0000000000..ef1184eec8 --- /dev/null +++ b/tools/python/xen/xm/resources.py @@ -0,0 +1,56 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Bryan D. Payne <bdpayne@us.ibm.com> +#============================================================================ + +"""List the resource label information from the global resource label file +""" +import sys, os +import string +from xen.util import dictio +from xen.util import security + +def usage(): + print "\nUsage: xm resource\n" + print " This program lists information for each resource in the" + print " global resource label file\n" + + +def print_resource_data(access_control): + """Prints out a resource dictionary to stdout + """ + for resource in access_control: + (policy, label) = access_control[resource] + print resource + print " policy: "+policy + print " label: "+label + + +def main (argv): + try: + file = security.res_label_filename + access_control = dictio.dict_read("resources", file) + except: + print "Resource file not found." + return + + print_resource_data(access_control) + + +if __name__ == '__main__': + main(sys.argv) + + diff --git a/tools/python/xen/xm/rmlabel.py b/tools/python/xen/xm/rmlabel.py new file mode 100644 index 0000000000..ebd94a3163 --- /dev/null +++ b/tools/python/xen/xm/rmlabel.py @@ -0,0 +1,118 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Bryan D. Payne <bdpayne@us.ibm.com> +#============================================================================ + +"""Remove a label from a domain configuration file or a resoruce. +""" +import sys, os, re +import string +import traceback +from xen.util import dictio +from xen.util import security + +def usage(): + print "\nUsage: xm rmlabel dom <configfile>" + print " xm rmlabel res <resource>\n" + print " This program removes an acm_label entry from the 'configfile'" + print " for a domain or from the global resource label file for a" + print " resource. If the label does not exist for the given domain or" + print " resource, then rmlabel fails.\n" + + +def rm_resource_label(resource): + """Removes a resource label from the global resource label file. + """ + # read in the resource file + file = security.res_label_filename + try: + access_control = dictio.dict_read("resources", file) + except: + security.err("Resource file not found, cannot remove label!") + + # remove the entry and update file + if access_control.has_key(resource): + del access_control[resource] + dictio.dict_write(access_control, "resources", file) + else: + security.err("Label does not exist in resource label file.") + + +def rm_domain_label(configfile): + # open the domain config file + fd = None + file = None + if configfile[0] == '/': + fd = open(configfile, "rb") + else: + for prefix in [".", "/etc/xen"]: + file = prefix + "/" + configfile + if os.path.isfile(file): + fd = open(file, "rb") + break + if not fd: + security.err("Configuration file '"+configfile+"' not found.") + + # read in the domain config file, removing label + ac_entry_re = re.compile("^access_control\s*=.*", re.IGNORECASE) + ac_exit_re = re.compile(".*'\].*") + file_contents = "" + comment = 0 + removed = 0 + for line in fd.readlines(): + if ac_entry_re.match(line): + comment = 1 + if comment: + removed = 1 + line = "#"+line + if comment and ac_exit_re.match(line): + comment = 0 + file_contents = file_contents + line + fd.close() + + # send error message if we didn't find anything to remove + if not removed: + security.err("Label does not exist in domain configuration file.") + + # write the data back out to the file + fd = open(file, "wb") + fd.writelines(file_contents) + fd.close() + + +def main (argv): + try: + if len(argv) != 3: + usage() + return + + if argv[1].lower() == "dom": + configfile = argv[2] + rm_domain_label(configfile) + elif argv[1].lower() == "res": + resource = argv[2] + rm_resource_label(resource) + else: + usage() + + except security.ACMError: + traceback.print_exc(limit=1) + + +if __name__ == '__main__': + main(sys.argv) + + |
