# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1186672496 -3600
# Node ID f0298301ba8b34ac3e5470cf953a3591f7730d26
# Parent 3876b4e7cc0a4d0404ca01fce0879d85cb98d213
acm: Some fixes to the Xend ACM management code
- prevent vlans from being relabeled when they are in use by the
current policy
- fix problems when doing an update of the policy and the name of the
policy changes while doing that
- refactor code that has to take into consideration that unlabeled
domains may be defined using the label __UNLABELED__
- make 'xm list --label' show the complete label of a domain
Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
---
tools/python/xen/util/acmpolicy.py | 21 +++++++---
tools/python/xen/util/security.py | 64 ++++++++++++++++++++++++--------
tools/python/xen/xend/XendDomainInfo.py | 26 ++++++++++---
tools/python/xen/xm/main.py | 2 -
4 files changed, 84 insertions(+), 29 deletions(-)
diff -r 3876b4e7cc0a -r f0298301ba8b tools/python/xen/util/acmpolicy.py
--- a/tools/python/xen/util/acmpolicy.py Thu Aug 09 16:02:33 2007 +0100
+++ b/tools/python/xen/util/acmpolicy.py Thu Aug 09 16:14:56 2007 +0100
@@ -191,20 +191,21 @@ class ACMPolicy(XSPolicy):
acmpol_old.policy_get_virtualmachinelabel_names_sorted()
del_array = ""
chg_array = ""
+
for o in oldvmnames:
if o not in newvmnames:
- old_idx = oldvmnames.index(o) + 1 # for _NULL_LABEL_
+ old_idx = oldvmnames.index(o)
if vmlabel_map.has_key(o):
#not a deletion, but a renaming
new = vmlabel_map[o]
- new_idx = newvmnames.index(new) + 1 # for _NULL_LABEL_
+ new_idx = newvmnames.index(new)
chg_array += struct.pack("ii", old_idx, new_idx)
else:
del_array += struct.pack("i", old_idx)
for v in newvmnames:
if v in oldvmnames:
- old_idx = oldvmnames.index(v) + 1 # for _NULL_LABEL_
- new_idx = newvmnames.index(v) + 1 # for _NULL_LABEL_
+ old_idx = oldvmnames.index(v)
+ new_idx = newvmnames.index(v)
if old_idx != new_idx:
chg_array += struct.pack("ii", old_idx, new_idx)
@@ -348,7 +349,7 @@ class ACMPolicy(XSPolicy):
ssidref = xsconstants.INVALID_SSIDREF
names = self.policy_get_virtualmachinelabel_names_sorted()
try:
- vmidx = names.index(vm_label) + 1 # for _NULL_LABEL_
+ vmidx = names.index(vm_label)
ssidref = (vmidx << 16) | vmidx
except:
pass
@@ -618,6 +619,9 @@ class ACMPolicy(XSPolicy):
vmnames.remove(bootstrap)
vmnames.sort()
vmnames.insert(0, bootstrap)
+ if ACM_LABEL_UNLABELED in vmnames:
+ vmnames.remove(ACM_LABEL_UNLABELED)
+ vmnames.insert(0, ACM_LABEL_UNLABELED)
return vmnames
def policy_get_virtualmachinelabel_names_sorted(self):
@@ -625,7 +629,10 @@ class ACMPolicy(XSPolicy):
label will be the first one in that list, followed
by an alphabetically sorted list of VM label names """
vmnames = self.policy_get_virtualmachinelabel_names()
- return self.policy_sort_virtualmachinelabel_names(vmnames)
+ res = self.policy_sort_virtualmachinelabel_names(vmnames)
+ if res[0] != ACM_LABEL_UNLABELED:
+ res.insert(0, ACM_LABEL_UNLABELED)
+ return res
def policy_get_virtualmachinelabels(self):
""" Get a list of all virtual machine labels in this policy """
@@ -906,7 +913,7 @@ class ACMPolicy(XSPolicy):
allvmtypes = self.policy_get_virtualmachinelabel_names_sorted()
except:
return None
- return allvmtypes[chwall_ref-1] # skip _NULL_LABEL_
+ return allvmtypes[chwall_ref]
def policy_get_domain_label_formatted(self, domid):
label = self.policy_get_domain_label(domid)
diff -r 3876b4e7cc0a -r f0298301ba8b tools/python/xen/util/security.py
--- a/tools/python/xen/util/security.py Thu Aug 09 16:02:33 2007 +0100
+++ b/tools/python/xen/util/security.py Thu Aug 09 16:14:56 2007 +0100
@@ -838,13 +838,28 @@ def set_resource_label_xapi(resource, re
def is_resource_in_use(resource):
- """ Investigate all running domains whether they use this device """
+ """
+ Domain-0 'owns' resources of type 'VLAN', the rest are owned by
+ the guests.
+ """
from xen.xend import XendDomain
- dominfos = XendDomain.instance().list('all')
lst = []
- for dominfo in dominfos:
- if is_resource_in_use_by_dom(dominfo, resource):
- lst.append(dominfo)
+ if resource.startswith('vlan'):
+ from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
+ curpol = XSPolicyAdminInstance().get_loaded_policy()
+ policytype, label, policy = get_res_label(resource)
+ if curpol and \
+ policytype == xsconstants.ACM_POLICY_ID and \
+ policy == curpol.get_name() and \
+ label in curpol.policy_get_resourcelabel_names():
+ # VLAN is in use.
+ lst.append(XendDomain.instance().
+ get_vm_by_uuid(XendDomain.DOM0_UUID))
+ else:
+ dominfos = XendDomain.instance().list('all')
+ for dominfo in dominfos:
+ if is_resource_in_use_by_dom(dominfo, resource):
+ lst.append(dominfo)
return lst
def devices_equal(res1, res2, mustexist=True):
@@ -892,6 +907,10 @@ def get_domain_resources(dominfo):
if sec_lab:
resources[typ].append(sec_lab)
else:
+ # !!! This should really get the label of the domain
+ # or at least a resource label that has the same STE type
+ # as the domain has
+ from xen.util.acmpolicy import ACM_LABEL_UNLABELED
resources[typ].append("%s:%s:%s" %
(xsconstants.ACM_POLICY_ID,
active_policy,
@@ -924,7 +943,8 @@ def resources_compatible_with_vmlabel(xs
def __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
- access_control):
+ access_control,
+ is_policy_update=False):
"""
Check whether the resources' labels are compatible with the
given VM label. The access_control parameter provides a
@@ -955,15 +975,23 @@ def __resources_compatible_with_vmlabel(
elif key in [ 'vif' ]:
for xapi_label in value:
label = xapi_label.split(":")
- if not collect_labels(reslabels, label, polname):
- return False
+ from xen.util.acmpolicy import ACM_LABEL_UNLABELED
+ if not (is_policy_update and \
+ label[2] == ACM_LABEL_UNLABELED):
+ if not collect_labels(reslabels, label, polname):
+ return False
else:
log.error("Unhandled device type: %s" % key)
return False
# Check that all resource labes have a common STE type with the
# vmlabel
- rc = xspol.policy_check_vmlabel_against_reslabels(vmlabel, reslabels)
+ if len(reslabels) > 0:
+ rc = xspol.policy_check_vmlabel_against_reslabels(vmlabel, reslabels)
+ else:
+ rc = True
+ log.info("vmlabel=%s, reslabels=%s, rc=%s" %
+ (vmlabel, reslabels, str(rc)))
return rc;
def set_resource_label(resource, policytype, policyref, reslabel, \
@@ -1234,11 +1262,12 @@ def change_acm_policy(bin_pol, del_array
compatible = __resources_compatible_with_vmlabel(new_acmpol,
dominfo,
new_vmlabel,
- access_control)
+ access_control,
+ is_policy_update=True)
log.info("Domain %s with new label '%s' can access its "
"resources? : %s" %
(name, new_vmlabel, str(compatible)))
- log.info("VM labels in new domain: %s" %
+ log.info("VM labels in new policy: %s" %
new_acmpol.policy_get_virtualmachinelabel_names())
if not compatible:
return (-xsconstants.XSERR_RESOURCE_ACCESS, "")
@@ -1252,11 +1281,16 @@ def change_acm_policy(bin_pol, del_array
sec_lab, new_seclab = labels
if sec_lab != new_seclab:
log.info("Updating domain %s to new label '%s'." % \
- (sec_lab, new_seclab))
+ (dominfo.getName(), new_seclab))
# This better be working!
- dominfo.set_security_label(new_seclab,
- sec_lab,
- new_acmpol)
+ res = dominfo.set_security_label(new_seclab,
+ sec_lab,
+ new_acmpol,
+ cur_acmpol)
+ if res[0] != xsconstants.XSERR_SUCCESS:
+ log.info("ERROR: Could not chg label on domain %s: %s"
%
+ (dominfo.getName(),
+ xsconstants.xserr2string(-int(res[0]))))
finally:
log.info("----------------------------------------------")
mapfile_unlock()
diff -r 3876b4e7cc0a -r f0298301ba8b tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Thu Aug 09 16:02:33 2007 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py Thu Aug 09 16:14:56 2007 +0100
@@ -2187,11 +2187,18 @@ class XendDomainInfo:
return self.metrics.get_uuid();
- def get_security_label(self):
+ def get_security_label(self, xspol=None):
+ """
+ Get the security label of a domain
+ @param xspol The policy to use when converting the ssid into
+ a label; only to be passed during the updating
+ of the policy
+ """
domid = self.getDomid()
- from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
- xspol = XSPolicyAdminInstance().get_loaded_policy()
+ if not xspol:
+ from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
+ xspol = XSPolicyAdminInstance().get_loaded_policy()
if domid == 0:
if xspol:
@@ -2202,7 +2209,8 @@ class XendDomainInfo:
label = self.info.get('security_label', '')
return label
- def set_security_label(self, seclab, old_seclab, xspol=None):
+ def set_security_label(self, seclab, old_seclab, xspol=None,
+ xspol_old=None):
"""
Set the security label of a domain from its old to
a new value.
@@ -2213,6 +2221,8 @@ class XendDomainInfo:
@param xspol An optional policy under which this
update should be done. If not given,
then the current active policy is used.
+ @param xspol_old The old policy; only to be passed during
+ the updating of a policy
@return Returns return code, a string with errors from
the hypervisor's operation, old label of the
domain
@@ -2223,6 +2233,7 @@ class XendDomainInfo:
new_ssidref = 0
domid = self.getDomid()
res_labels = None
+ is_policy_update = (xspol_old != None)
from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
from xen.util import xsconstants
@@ -2276,13 +2287,16 @@ class XendDomainInfo:
# Check that all used resources are accessible under the
# new label
- if not security.resources_compatible_with_vmlabel(xspol,
+ if not is_policy_update and \
+ not security.resources_compatible_with_vmlabel(xspol,
self, label):
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
#Check label against expected one.
- old_label = self.get_security_label()
+ old_label = self.get_security_label(xspol_old)
if old_label != old_seclab:
+ log.info("old_label != old_seclab: %s != %s" %
+ (old_label, old_seclab))
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
# relabel domain in the hypervisor
diff -r 3876b4e7cc0a -r f0298301ba8b tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Thu Aug 09 16:02:33 2007 +0100
+++ b/tools/python/xen/xm/main.py Thu Aug 09 16:14:56 2007 +0100
@@ -876,7 +876,7 @@ def parse_doms_info(info):
if len(tmp) != 3:
seclabel = ""
else:
- seclabel = tmp[2]
+ seclabel = security_label
parsed_info['seclabel'] = seclabel
if serverType == SERVER_XEN_API:
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|