mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Extend 'xm dumppolicy' to support Xen-API
I am extending 'xm dumppolicy' to be used via the Xen-API. For this there are two new functions in the ACM policy class: - get the currently enforced policy including statistical data from the hypervisor - get the ACM 'ssidref' of a Domain. Since this may be a ACM-specific variable or type (int) I put it into the ACM class. I extended the Xen-API documentation with the two new functions. Signed-off-by: Stefan Berger <Stefanb@us.ibm.com>
This commit is contained in:
1 parent
ac9ba8d39d
commit
8950f5c6ba
10 files changed
+369
-41
No files matched your search
@@ -26,6 +26,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <xen/xsm/acm.h>
|
||||
@@ -258,6 +259,41 @@ static PyObject *chgpolicy(PyObject *self, PyObject *args)
|
||||
}
|
||||
|
||||
|
||||
static PyObject *getpolicy(PyObject *self, PyObject *args)
|
||||
{
|
||||
struct acm_getpolicy getpolicy;
|
||||
int xc_handle, rc;
|
||||
uint8_t pull_buffer[8192];
|
||||
PyObject *result;
|
||||
uint32_t len = sizeof(pull_buffer);
|
||||
|
||||
memset(&getpolicy, 0x0, sizeof(getpolicy));
|
||||
set_xen_guest_handle(getpolicy.pullcache, pull_buffer);
|
||||
getpolicy.pullcache_size = sizeof(pull_buffer);
|
||||
|
||||
if ((xc_handle = xc_interface_open()) <= 0) {
|
||||
PyErr_SetString(PyExc_IOError, ctrlif_op);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
|
||||
|
||||
xc_interface_close(xc_handle);
|
||||
|
||||
if (rc == 0) {
|
||||
struct acm_policy_buffer *header =
|
||||
(struct acm_policy_buffer *)pull_buffer;
|
||||
if (ntohl(header->len) < sizeof(pull_buffer))
|
||||
len = ntohl(header->len);
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
result = Py_BuildValue("is#", rc, pull_buffer, len);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *relabel_domains(PyObject *self, PyObject *args)
|
||||
{
|
||||
struct acm_relabel_doms reldoms;
|
||||
@@ -313,6 +349,7 @@ static PyMethodDef acmMethods[] = {
|
||||
{"getssid", getssid, METH_VARARGS, "Retrieve label information and ssidref for a domain"},
|
||||
{"getdecision", getdecision, METH_VARARGS, "Retrieve ACM access control decision"},
|
||||
{"chgpolicy", chgpolicy, METH_VARARGS, "Change the policy in one step"},
|
||||
{"getpolicy", getpolicy, METH_NOARGS , "Get the binary policy from the hypervisor"},
|
||||
{"relabel_domains", relabel_domains, METH_VARARGS, "Relabel domains"},
|
||||
/* end of list (extend list above this line) */
|
||||
{NULL, NULL, 0, NULL}
|
||||
|
||||
@@ -1264,3 +1264,11 @@ class ACMPolicy(XSPolicy):
|
||||
log.info("The following Ch. Wall types in labels were unknown:" \
|
||||
" %s" % list(unknown_chw))
|
||||
return rc, mapfile, all_bin.tostring()
|
||||
|
||||
def get_enforced_binary(self):
|
||||
rc, binpol = security.hv_get_policy()
|
||||
if rc != 0:
|
||||
raise SecurityError(-xsconstants.XSERR_HV_OP_FAILED)
|
||||
return binpol
|
||||
|
||||
get_enforced_binary = classmethod(get_enforced_binary)
|
||||
@@ -507,6 +507,22 @@ def hv_chg_policy(bin_pol, del_array, chg_array):
|
||||
rc = -xsconstants.XSERR_HV_OP_FAILED
|
||||
return rc, errors
|
||||
|
||||
def hv_get_policy():
|
||||
"""
|
||||
Gte the binary policy enforced in the hypervisor
|
||||
"""
|
||||
rc = -xsconstants.XSERR_GENERAL_FAILURE
|
||||
bin_pol = ""
|
||||
if not on():
|
||||
err("No policy active.")
|
||||
try:
|
||||
rc, bin_pol = acm.getpolicy()
|
||||
except Exception, e:
|
||||
pass
|
||||
if len(bin_pol) == 0:
|
||||
bin_pol = None
|
||||
return rc, bin_pol
|
||||
|
||||
|
||||
def make_policy(policy_name):
|
||||
policy_file = string.join(string.split(policy_name, "."), "/")
|
||||
@@ -546,10 +562,22 @@ def dump_policy():
|
||||
|
||||
(ret, output) = commands.getstatusoutput(xensec_tool + " getpolicy")
|
||||
if ret:
|
||||
err("Dumping hypervisor policy failed:\n" + output)
|
||||
err("Dumping hypervisor policy failed:\n" + output)
|
||||
|
||||
print output
|
||||
|
||||
|
||||
def dump_policy_file(filename, ssidref=None):
|
||||
ssid = ""
|
||||
if ssidref:
|
||||
ssid = " " + str(ssidref)
|
||||
(ret, output) = commands.getstatusoutput(xensec_tool + " dumppolicy " +
|
||||
filename + ssid)
|
||||
if ret:
|
||||
err("Dumping policy failed:\n" + output)
|
||||
|
||||
print output
|
||||
|
||||
|
||||
def list_labels(policy_name, condition):
|
||||
if (not policy_name) and (active_policy) in ["NULL", "INACTIVE", "DEFAULT"]:
|
||||
|
||||
@@ -16,13 +16,15 @@
|
||||
# Copyright (c) 2006 Xensource
|
||||
#============================================================================
|
||||
|
||||
import base64
|
||||
import logging
|
||||
from xen.xend import XendDomain
|
||||
from xen.xend.XendBase import XendBase
|
||||
from xen.xend.XendError import *
|
||||
from xen.xend.XendAPIConstants import *
|
||||
from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
|
||||
from xen.util import xsconstants
|
||||
import xen.util.xsm.xsm as security
|
||||
import base64
|
||||
|
||||
log = logging.getLogger("xend.XendXSPolicy")
|
||||
log.setLevel(logging.TRACE)
|
||||
@@ -184,8 +186,13 @@ class XendACMPolicy(XendXSPolicy):
|
||||
'header' ]
|
||||
return XendXSPolicy.getAttrRO() + attrRO
|
||||
|
||||
def getFuncs(self):
|
||||
funcs = [ 'get_enforced_binary', 'get_VM_ssidref' ]
|
||||
return XendBase.getFuncs() + funcs
|
||||
|
||||
getClass = classmethod(getClass)
|
||||
getAttrRO = classmethod(getAttrRO)
|
||||
getFuncs = classmethod(getFuncs)
|
||||
|
||||
def __init__(self, acmpol, record, uuid):
|
||||
""" acmpol = actual ACMPolicy object """
|
||||
@@ -221,3 +228,25 @@ class XendACMPolicy(XendXSPolicy):
|
||||
def get_binary(self):
|
||||
polbin = self.acmpol.get_bin()
|
||||
return base64.b64encode(polbin)
|
||||
|
||||
def get_VM_ssidref(self, vm_ref):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
if not dom:
|
||||
raise InvalidHandleError("VM", vm_ref)
|
||||
if dom._stateGet() not in [ XEN_API_VM_POWER_STATE_RUNNING, \
|
||||
XEN_API_VM_POWER_STATE_PAUSED ]:
|
||||
raise VMBadState("Domain is not running or paused.")
|
||||
ssid = security.get_ssid(dom.getDomid())
|
||||
if not ssid:
|
||||
raise SecurityError(-xsconstants.XSERR_GENERAL_FAILURE)
|
||||
return ssid[3]
|
||||
|
||||
def get_enforced_binary(self):
|
||||
polbin = XSPolicyAdminInstance(). \
|
||||
get_enforced_binary(xsconstants.XS_POLICY_ACM)
|
||||
if polbin:
|
||||
return base64.b64encode(polbin)
|
||||
return None
|
||||
|
||||
get_enforced_binary = classmethod(get_enforced_binary)
|
||||
get_VM_ssidref = classmethod(get_VM_ssidref)
|
||||
@@ -324,6 +324,11 @@ class XSPolicyAdmin:
|
||||
stes = loadedpol.policy_get_stes_of_vmlabel(tmp[2])
|
||||
return stes
|
||||
|
||||
def get_enforced_binary(self, xstype):
|
||||
res = None
|
||||
if xstype == xsconstants.XS_POLICY_ACM:
|
||||
res = ACMPolicy.get_enforced_binary()
|
||||
return res
|
||||
|
||||
poladmin = None
|
||||
|
||||
|
||||
@@ -17,9 +17,18 @@
|
||||
#============================================================================
|
||||
"""Display currently enforced policy (low-level hypervisor representation).
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
from xen.util.xsm.xsm import XSMError, err, dump_policy
|
||||
import base64
|
||||
import tempfile
|
||||
import commands
|
||||
from xen.util.xsm.xsm import XSMError, err, dump_policy, dump_policy_file
|
||||
from xen.xm.opts import OptionError
|
||||
from xen.xm import main as xm_main
|
||||
from xen.xm.main import server
|
||||
from xen.util import xsconstants
|
||||
|
||||
DOM0_UUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
def help():
|
||||
return """
|
||||
@@ -30,7 +39,25 @@ def main(argv):
|
||||
if len(argv) != 1:
|
||||
raise OptionError("No arguments expected.")
|
||||
|
||||
dump_policy()
|
||||
if xm_main.serverType == xm_main.SERVER_XEN_API:
|
||||
try:
|
||||
bin_pol = server.xenapi.ACMPolicy.get_enforced_binary()
|
||||
if bin_pol:
|
||||
dom0_ssid = server.xenapi.ACMPolicy.get_VM_ssidref(DOM0_UUID)
|
||||
bin = base64.b64decode(bin_pol)
|
||||
try:
|
||||
fd, filename = tempfile.mkstemp(suffix=".bin")
|
||||
os.write(fd, bin)
|
||||
os.close(fd)
|
||||
dump_policy_file(filename, dom0_ssid)
|
||||
finally:
|
||||
os.unlink(filename)
|
||||
else:
|
||||
err("No policy is installed.")
|
||||
except Exception, e:
|
||||
err("An error occurred getting the running policy: %s" % str(e))
|
||||
else:
|
||||
dump_policy()
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
|
||||