-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Is this acceptable to upstream?
Dan
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora -
http://enigmail.mozdev.org
iEYEARECAAYFAkma48EACgkQrlYvE4MpobMSBwCfXJnrlgoM0CuwdxF8BzcoQVvr
5pIAoNcKSrh+YsxNMjk8RgM4E7feUc4R
=iLJG
-----END PGP SIGNATURE-----
diff -up libvirt-0.6.0/include/libvirt/libvirt.h.in.svirt
libvirt-0.6.0/include/libvirt/libvirt.h.in
--- libvirt-0.6.0/include/libvirt/libvirt.h.in.svirt 2009-01-20 08:48:27.000000000 -0500
+++ libvirt-0.6.0/include/libvirt/libvirt.h.in 2009-02-17 10:07:06.215686000 -0500
@@ -111,6 +111,68 @@ typedef enum {
} virDomainCreateFlags;
/**
+ * VIR_SECURITY_LABEL_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityLabel label string.
+ * Note that this value is based on that used by Labeled NFS.
+ */
+#define VIR_SECURITY_LABEL_BUFLEN (4096 + 1)
+
+/**
+ * virSecurityLabel:
+ *
+ * a virSecurityLabel is a structure filled by virDomainGetSecurityLabel(),
+ * providing the security label and associated attributes for the specified
+ * domain.
+ *
+ */
+typedef struct _virSecurityLabel {
+ char label[VIR_SECURITY_LABEL_BUFLEN]; /* security label string */
+ int enforcing; /* 1 if security policy is being enforced
for domain */
+} virSecurityLabel;
+
+/**
+ * virSecurityLabelPtr:
+ *
+ * a virSecurityLabelPtr is a pointer to a virSecurityLabel.
+ */
+typedef virSecurityLabel *virSecurityLabelPtr;
+
+/**
+ * VIR_SECURITY_MODEL_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityModel model string.
+ */
+#define VIR_SECURITY_MODEL_BUFLEN (256 + 1)
+
+/**
+ * VIR_SECURITY_DOI_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityModel doi string.
+ */
+#define VIR_SECURITY_DOI_BUFLEN (256 + 1)
+
+/**
+ * virSecurityModel:
+ *
+ * a virSecurityModel is a structure filled by virNodeGetSecurityModel(),
+ * providing the per-hypervisor security model and DOI attributes for the
+ * specified domain.
+ *
+ */
+typedef struct _virSecurityModel {
+ char model[VIR_SECURITY_MODEL_BUFLEN]; /* security model string */
+ char doi[VIR_SECURITY_DOI_BUFLEN]; /* domain of interpetation */
+} virSecurityModel;
+
+/**
+ * virSecurityModelPtr:
+ *
+ * a virSecurityModelPtr is a pointer to a virSecurityModel.
+ */
+typedef virSecurityModel *virSecurityModelPtr;
+
+/**
* virNodeInfoPtr:
*
* a virNodeInfo is a structure filled by virNodeGetInfo() and providing
@@ -417,6 +479,9 @@ char * virConnectGetCap
unsigned long long virNodeGetFreeMemory (virConnectPtr conn);
+int virNodeGetSecurityModel (virConnectPtr conn,
+ virSecurityModelPtr secmodel);
+
/*
* Gather list of running domains
*/
@@ -506,6 +571,8 @@ int virDomainSetMaxM
int virDomainSetMemory (virDomainPtr domain,
unsigned long memory);
int virDomainGetMaxVcpus (virDomainPtr domain);
+int virDomainGetSecurityLabel (virDomainPtr domain,
+ virSecurityLabelPtr seclabel);
/*
* XML domain description
diff -up libvirt-0.6.0/include/libvirt/libvirt.h.svirt
libvirt-0.6.0/include/libvirt/libvirt.h
--- libvirt-0.6.0/include/libvirt/libvirt.h.svirt 2009-01-31 04:20:10.000000000 -0500
+++ libvirt-0.6.0/include/libvirt/libvirt.h 2009-02-17 10:07:32.421570000 -0500
@@ -111,6 +111,68 @@ typedef enum {
} virDomainCreateFlags;
/**
+ * VIR_SECURITY_LABEL_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityLabel label string.
+ * Note that this value is based on that used by Labeled NFS.
+ */
+#define VIR_SECURITY_LABEL_BUFLEN (4096 + 1)
+
+/**
+ * virSecurityLabel:
+ *
+ * a virSecurityLabel is a structure filled by virDomainGetSecurityLabel(),
+ * providing the security label and associated attributes for the specified
+ * domain.
+ *
+ */
+typedef struct _virSecurityLabel {
+ char label[VIR_SECURITY_LABEL_BUFLEN]; /* security label string */
+ int enforcing; /* 1 if security policy is being enforced
for domain */
+} virSecurityLabel;
+
+/**
+ * virSecurityLabelPtr:
+ *
+ * a virSecurityLabelPtr is a pointer to a virSecurityLabel.
+ */
+typedef virSecurityLabel *virSecurityLabelPtr;
+
+/**
+ * VIR_SECURITY_MODEL_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityModel model string.
+ */
+#define VIR_SECURITY_MODEL_BUFLEN (256 + 1)
+
+/**
+ * VIR_SECURITY_DOI_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityModel doi string.
+ */
+#define VIR_SECURITY_DOI_BUFLEN (256 + 1)
+
+/**
+ * virSecurityModel:
+ *
+ * a virSecurityModel is a structure filled by virNodeGetSecurityModel(),
+ * providing the per-hypervisor security model and DOI attributes for the
+ * specified domain.
+ *
+ */
+typedef struct _virSecurityModel {
+ char model[VIR_SECURITY_MODEL_BUFLEN]; /* security model string */
+ char doi[VIR_SECURITY_DOI_BUFLEN]; /* domain of interpetation */
+} virSecurityModel;
+
+/**
+ * virSecurityModelPtr:
+ *
+ * a virSecurityModelPtr is a pointer to a virSecurityModel.
+ */
+typedef virSecurityModel *virSecurityModelPtr;
+
+/**
* virNodeInfoPtr:
*
* a virNodeInfo is a structure filled by virNodeGetInfo() and providing
@@ -417,6 +479,9 @@ char * virConnectGetCap
unsigned long long virNodeGetFreeMemory (virConnectPtr conn);
+int virNodeGetSecurityModel (virConnectPtr conn,
+ virSecurityModelPtr secmodel);
+
/*
* Gather list of running domains
*/
@@ -506,6 +571,8 @@ int virDomainSetMaxM
int virDomainSetMemory (virDomainPtr domain,
unsigned long memory);
int virDomainGetMaxVcpus (virDomainPtr domain);
+int virDomainGetSecurityLabel (virDomainPtr domain,
+ virSecurityLabelPtr seclabel);
/*
* XML domain description
diff -up libvirt-0.6.0/include/libvirt/virterror.h.svirt
libvirt-0.6.0/include/libvirt/virterror.h
--- libvirt-0.6.0/include/libvirt/virterror.h.svirt 2008-11-25 08:42:33.000000000 -0500
+++ libvirt-0.6.0/include/libvirt/virterror.h 2009-02-17 10:07:06.223677000 -0500
@@ -61,6 +61,7 @@ typedef enum {
VIR_FROM_UML, /* Error at the UML driver */
VIR_FROM_NODEDEV, /* Error from node device monitor */
VIR_FROM_XEN_INOTIFY, /* Error from xen inotify layer */
+ VIR_FROM_SECURITY, /* Error from security framework */
} virErrorDomain;
@@ -154,6 +155,7 @@ typedef enum {
VIR_WAR_NO_NODE, /* failed to start node driver */
VIR_ERR_INVALID_NODE_DEVICE,/* invalid node device object */
VIR_ERR_NO_NODE_DEVICE,/* node device not found */
+ VIR_ERR_NO_SECURITY_MODEL, /* security model not found */
} virErrorNumber;
/**
diff -up libvirt-0.6.0/po/POTFILES.in.svirt libvirt-0.6.0/po/POTFILES.in
--- libvirt-0.6.0/po/POTFILES.in.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/po/POTFILES.in 2009-02-17 10:07:06.226679000 -0500
@@ -22,6 +22,8 @@ src/proxy_internal.c
src/qemu_conf.c
src/qemu_driver.c
src/remote_internal.c
+src/security.c
+src/security_selinux.c
src/storage_backend.c
src/storage_backend_disk.c
src/storage_backend_fs.c
diff -up libvirt-0.6.0/python/generator.py.svirt libvirt-0.6.0/python/generator.py
--- libvirt-0.6.0/python/generator.py.svirt 2008-11-21 07:47:32.000000000 -0500
+++ libvirt-0.6.0/python/generator.py 2009-02-17 10:07:06.230676000 -0500
@@ -342,6 +342,8 @@ skip_function = (
'virCopyLastError', # Python API is called virGetLastError instead
'virConnectOpenAuth', # Python C code is manually written
'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
+ 'virDomainGetSecurityLabel', # Needs investigation...
+ 'virNodeGetSecurityModel', # Needs investigation...
'virConnectDomainEventRegister', # overridden in virConnect.py
'virConnectDomainEventDeregister', # overridden in virConnect.py
)
diff -up libvirt-0.6.0/qemud/Makefile.am.svirt libvirt-0.6.0/qemud/Makefile.am
--- libvirt-0.6.0/qemud/Makefile.am.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/qemud/Makefile.am 2009-02-17 10:07:06.237678000 -0500
@@ -130,6 +130,7 @@ libvirtd_LDADD += ../src/libvirt_driver_
endif
endif
+libvirtd_LDADD += ../src/libvirt_driver_security.la
libvirtd_LDADD += ../src/libvirt.la
if HAVE_POLKIT
diff -up libvirt-0.6.0/qemud/remote.c.svirt libvirt-0.6.0/qemud/remote.c
--- libvirt-0.6.0/qemud/remote.c.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/qemud/remote.c 2009-02-17 10:07:06.246680000 -0500
@@ -1340,6 +1340,76 @@ remoteDispatchDomainGetMaxVcpus (struct
}
static int
+remoteDispatchDomainGetSecurityLabel(struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_domain_get_security_label_args *args,
+ remote_domain_get_security_label_ret *ret)
+{
+ virDomainPtr dom;
+ virSecurityLabel seclabel;
+
+ dom = get_nonnull_domain(conn, args->dom);
+ if (dom == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ memset(&seclabel, 0, sizeof seclabel);
+ if (virDomainGetSecurityLabel(dom, &seclabel) == -1) {
+ virDomainFree(dom);
+ remoteDispatchFormatError(rerr, "%s", _("unable to get security
label"));
+ return -1;
+ }
+
+ ret->label.label_len = strlen(seclabel.label) + 1;
+ if (VIR_ALLOC_N(ret->label.label_val, ret->label.label_len) < 0) {
+ virDomainFree(dom);
+ remoteDispatchOOMError(rerr);
+ return -1;
+ }
+ strcpy(ret->label.label_val, seclabel.label);
+ ret->enforcing = seclabel.enforcing;
+ virDomainFree(dom);
+
+ return 0;
+}
+
+static int
+remoteDispatchNodeGetSecurityModel(struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ void *args ATTRIBUTE_UNUSED,
+ remote_node_get_security_model_ret *ret)
+{
+ virSecurityModel secmodel;
+
+ memset(&secmodel, 0, sizeof secmodel);
+ if (virNodeGetSecurityModel(conn, &secmodel) == -1) {
+ remoteDispatchFormatError(rerr, "%s", _("unable to get security
model"));
+ return -1;
+ }
+
+ ret->model.model_len = strlen(secmodel.model) + 1;
+ if (VIR_ALLOC_N(ret->model.model_val, ret->model.model_len) < 0) {
+ remoteDispatchOOMError(rerr);
+ return -1;
+ }
+ strcpy(ret->model.model_val, secmodel.model);
+
+ ret->doi.doi_len = strlen(secmodel.doi) + 1;
+ if (VIR_ALLOC_N(ret->doi.doi_val, ret->doi.doi_len) < 0) {
+ remoteDispatchOOMError(rerr);
+ return -1;
+ }
+ strcpy(ret->doi.doi_val, secmodel.doi);
+
+ return 0;
+}
+
+static int
remoteDispatchDomainGetOsType (struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_client *client ATTRIBUTE_UNUSED,
virConnectPtr conn,
diff -up libvirt-0.6.0/qemud/remote_dispatch_args.h.svirt
libvirt-0.6.0/qemud/remote_dispatch_args.h
--- libvirt-0.6.0/qemud/remote_dispatch_args.h.svirt 2008-12-19 09:00:02.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_dispatch_args.h 2009-02-17 10:07:06.250678000 -0500
@@ -99,3 +99,4 @@
remote_node_device_get_parent_args val_remote_node_device_get_parent_args;
remote_node_device_num_of_caps_args val_remote_node_device_num_of_caps_args;
remote_node_device_list_caps_args val_remote_node_device_list_caps_args;
+ remote_domain_get_security_label_args val_remote_domain_get_security_label_args;
diff -up libvirt-0.6.0/qemud/remote_dispatch_prototypes.h.svirt
libvirt-0.6.0/qemud/remote_dispatch_prototypes.h
--- libvirt-0.6.0/qemud/remote_dispatch_prototypes.h.svirt 2008-12-19 09:00:02.000000000
-0500
+++ libvirt-0.6.0/qemud/remote_dispatch_prototypes.h 2009-02-17 10:07:06.255676000 -0500
@@ -184,6 +184,13 @@ static int remoteDispatchDomainGetSchedu
remote_error *err,
remote_domain_get_scheduler_type_args *args,
remote_domain_get_scheduler_type_ret *ret);
+static int remoteDispatchDomainGetSecurityLabel(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_domain_get_security_label_args *args,
+ remote_domain_get_security_label_ret *ret);
static int remoteDispatchDomainGetVcpus(
struct qemud_server *server,
struct qemud_client *client,
@@ -576,6 +583,13 @@ static int remoteDispatchNodeGetInfo(
remote_error *err,
void *args,
remote_node_get_info_ret *ret);
+static int remoteDispatchNodeGetSecurityModel(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ void *args,
+ remote_node_get_security_model_ret *ret);
static int remoteDispatchNodeListDevices(
struct qemud_server *server,
struct qemud_client *client,
diff -up libvirt-0.6.0/qemud/remote_dispatch_ret.h.svirt
libvirt-0.6.0/qemud/remote_dispatch_ret.h
--- libvirt-0.6.0/qemud/remote_dispatch_ret.h.svirt 2008-12-19 09:00:02.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_dispatch_ret.h 2009-02-17 10:07:06.259676000 -0500
@@ -86,3 +86,5 @@
remote_node_device_get_parent_ret val_remote_node_device_get_parent_ret;
remote_node_device_num_of_caps_ret val_remote_node_device_num_of_caps_ret;
remote_node_device_list_caps_ret val_remote_node_device_list_caps_ret;
+ remote_domain_get_security_label_ret val_remote_domain_get_security_label_ret;
+ remote_node_get_security_model_ret val_remote_node_get_security_model_ret;
diff -up libvirt-0.6.0/qemud/remote_dispatch_table.h.svirt
libvirt-0.6.0/qemud/remote_dispatch_table.h
--- libvirt-0.6.0/qemud/remote_dispatch_table.h.svirt 2008-12-19 09:00:02.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_dispatch_table.h 2009-02-17 10:07:06.263676000 -0500
@@ -592,3 +592,13 @@
.args_filter = (xdrproc_t) xdr_remote_node_device_list_caps_args,
.ret_filter = (xdrproc_t) xdr_remote_node_device_list_caps_ret,
},
+{ /* DomainGetSecurityLabel => 118 */
+ .fn = (dispatch_fn) remoteDispatchDomainGetSecurityLabel,
+ .args_filter = (xdrproc_t) xdr_remote_domain_get_security_label_args,
+ .ret_filter = (xdrproc_t) xdr_remote_domain_get_security_label_ret,
+},
+{ /* NodeGetSecurityModel => 119 */
+ .fn = (dispatch_fn) remoteDispatchNodeGetSecurityModel,
+ .args_filter = (xdrproc_t) xdr_void,
+ .ret_filter = (xdrproc_t) xdr_remote_node_get_security_model_ret,
+},
diff -up libvirt-0.6.0/qemud/remote_protocol.c.svirt
libvirt-0.6.0/qemud/remote_protocol.c
--- libvirt-0.6.0/qemud/remote_protocol.c.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_protocol.c 2009-02-17 10:07:06.268676000 -0500
@@ -1166,6 +1166,43 @@ xdr_remote_domain_get_max_vcpus_ret (XDR
}
bool_t
+xdr_remote_domain_get_security_label_args (XDR *xdrs,
remote_domain_get_security_label_args *objp)
+{
+
+ if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_domain_get_security_label_ret (XDR *xdrs, remote_domain_get_security_label_ret
*objp)
+{
+ char **objp_cpp0 = (char **) (void *) &objp->label.label_val;
+
+ if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->label.label_len,
REMOTE_SECURITY_LABEL_MAX,
+ sizeof (char), (xdrproc_t) xdr_char))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->enforcing))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_node_get_security_model_ret (XDR *xdrs, remote_node_get_security_model_ret
*objp)
+{
+ char **objp_cpp1 = (char **) (void *) &objp->doi.doi_val;
+ char **objp_cpp0 = (char **) (void *) &objp->model.model_val;
+
+ if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->model.model_len,
REMOTE_SECURITY_MODEL_MAX,
+ sizeof (char), (xdrproc_t) xdr_char))
+ return FALSE;
+ if (!xdr_array (xdrs, objp_cpp1, (u_int *) &objp->doi.doi_len,
REMOTE_SECURITY_DOI_MAX,
+ sizeof (char), (xdrproc_t) xdr_char))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_domain_attach_device_args (XDR *xdrs, remote_domain_attach_device_args *objp)
{
diff -up libvirt-0.6.0/qemud/remote_protocol.h.svirt
libvirt-0.6.0/qemud/remote_protocol.h
--- libvirt-0.6.0/qemud/remote_protocol.h.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_protocol.h 2009-02-17 10:07:06.274679000 -0500
@@ -38,6 +38,9 @@ typedef remote_nonnull_string *remote_st
#define REMOTE_AUTH_TYPE_LIST_MAX 20
#define REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX 65536
#define REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX 65536
+#define REMOTE_SECURITY_MODEL_MAX VIR_SECURITY_MODEL_BUFLEN
+#define REMOTE_SECURITY_LABEL_MAX VIR_SECURITY_LABEL_BUFLEN
+#define REMOTE_SECURITY_DOI_MAX VIR_SECURITY_DOI_BUFLEN
typedef char remote_uuid[VIR_UUID_BUFLEN];
@@ -637,6 +640,32 @@ struct remote_domain_get_max_vcpus_ret {
};
typedef struct remote_domain_get_max_vcpus_ret remote_domain_get_max_vcpus_ret;
+struct remote_domain_get_security_label_args {
+ remote_nonnull_domain dom;
+};
+typedef struct remote_domain_get_security_label_args
remote_domain_get_security_label_args;
+
+struct remote_domain_get_security_label_ret {
+ struct {
+ u_int label_len;
+ char *label_val;
+ } label;
+ int enforcing;
+};
+typedef struct remote_domain_get_security_label_ret
remote_domain_get_security_label_ret;
+
+struct remote_node_get_security_model_ret {
+ struct {
+ u_int model_len;
+ char *model_val;
+ } model;
+ struct {
+ u_int doi_len;
+ char *doi_val;
+ } doi;
+};
+typedef struct remote_node_get_security_model_ret remote_node_get_security_model_ret;
+
struct remote_domain_attach_device_args {
remote_nonnull_domain dom;
remote_nonnull_string xml;
@@ -1348,6 +1377,8 @@ enum remote_procedure {
REMOTE_PROC_NODE_DEVICE_GET_PARENT = 115,
REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS = 116,
REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 117,
+ REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 118,
+ REMOTE_PROC_NODE_GET_SECURITY_MODEL = 119,
};
typedef enum remote_procedure remote_procedure;
@@ -1474,6 +1505,9 @@ extern bool_t xdr_remote_domain_get_vcp
extern bool_t xdr_remote_domain_get_vcpus_ret (XDR *, remote_domain_get_vcpus_ret*);
extern bool_t xdr_remote_domain_get_max_vcpus_args (XDR *,
remote_domain_get_max_vcpus_args*);
extern bool_t xdr_remote_domain_get_max_vcpus_ret (XDR *,
remote_domain_get_max_vcpus_ret*);
+extern bool_t xdr_remote_domain_get_security_label_args (XDR *,
remote_domain_get_security_label_args*);
+extern bool_t xdr_remote_domain_get_security_label_ret (XDR *,
remote_domain_get_security_label_ret*);
+extern bool_t xdr_remote_node_get_security_model_ret (XDR *,
remote_node_get_security_model_ret*);
extern bool_t xdr_remote_domain_attach_device_args (XDR *,
remote_domain_attach_device_args*);
extern bool_t xdr_remote_domain_detach_device_args (XDR *,
remote_domain_detach_device_args*);
extern bool_t xdr_remote_domain_get_autostart_args (XDR *,
remote_domain_get_autostart_args*);
@@ -1679,6 +1713,9 @@ extern bool_t xdr_remote_domain_get_vcpu
extern bool_t xdr_remote_domain_get_vcpus_ret ();
extern bool_t xdr_remote_domain_get_max_vcpus_args ();
extern bool_t xdr_remote_domain_get_max_vcpus_ret ();
+extern bool_t xdr_remote_domain_get_security_label_args ();
+extern bool_t xdr_remote_domain_get_security_label_ret ();
+extern bool_t xdr_remote_node_get_security_model_ret ();
extern bool_t xdr_remote_domain_attach_device_args ();
extern bool_t xdr_remote_domain_detach_device_args ();
extern bool_t xdr_remote_domain_get_autostart_args ();
diff -up libvirt-0.6.0/qemud/remote_protocol.x.svirt
libvirt-0.6.0/qemud/remote_protocol.x
--- libvirt-0.6.0/qemud/remote_protocol.x.svirt 2008-12-19 07:51:11.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_protocol.x 2009-02-17 10:07:06.279676000 -0500
@@ -115,6 +115,21 @@ const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MA
*/
const REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX = 65536;
+/*
+ * Maximum length of a security model field.
+ */
+const REMOTE_SECURITY_MODEL_MAX = VIR_SECURITY_MODEL_BUFLEN;
+
+/*
+ * Maximum length of a security label field.
+ */
+const REMOTE_SECURITY_LABEL_MAX = VIR_SECURITY_LABEL_BUFLEN;
+
+/*
+ * Maximum length of a security DOI field.
+ */
+const REMOTE_SECURITY_DOI_MAX = VIR_SECURITY_DOI_BUFLEN;
+
/* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */
typedef opaque remote_uuid[VIR_UUID_BUFLEN];
@@ -617,6 +632,20 @@ struct remote_domain_get_max_vcpus_ret {
int num;
};
+struct remote_domain_get_security_label_args {
+ remote_nonnull_domain dom;
+};
+
+struct remote_domain_get_security_label_ret {
+ char label<REMOTE_SECURITY_LABEL_MAX>;
+ int enforcing;
+};
+
+struct remote_node_get_security_model_ret {
+ char model<REMOTE_SECURITY_MODEL_MAX>;
+ char doi<REMOTE_SECURITY_DOI_MAX>;
+};
+
struct remote_domain_attach_device_args {
remote_nonnull_domain dom;
remote_nonnull_string xml;
@@ -1223,7 +1252,10 @@ enum remote_procedure {
REMOTE_PROC_NODE_DEVICE_DUMP_XML = 114,
REMOTE_PROC_NODE_DEVICE_GET_PARENT = 115,
REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS = 116,
- REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 117
+ REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 117,
+
+ REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 118,
+ REMOTE_PROC_NODE_GET_SECURITY_MODEL = 119
};
/* Custom RPC structure. */
diff -up libvirt-0.6.0/src/capabilities.c.svirt libvirt-0.6.0/src/capabilities.c
--- libvirt-0.6.0/src/capabilities.c.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/capabilities.c 2009-02-17 10:07:06.285678000 -0500
@@ -150,6 +150,8 @@ virCapabilitiesFree(virCapsPtr caps) {
VIR_FREE(caps->host.migrateTrans);
VIR_FREE(caps->host.arch);
+ VIR_FREE(caps->host.secModel.model);
+ VIR_FREE(caps->host.secModel.doi);
VIR_FREE(caps);
}
@@ -599,6 +601,14 @@ virCapabilitiesFormatXML(virCapsPtr caps
virBufferAddLit(&xml, " </cells>\n");
virBufferAddLit(&xml, " </topology>\n");
}
+
+ if (caps->host.secModel.model) {
+ virBufferAddLit(&xml, " <secmodel>\n");
+ virBufferVSprintf(&xml, " <model>%s</model>\n",
caps->host.secModel.model);
+ virBufferVSprintf(&xml, " <doi>%s</doi>\n",
caps->host.secModel.doi);
+ virBufferAddLit(&xml, " </secmodel>\n");
+ }
+
virBufferAddLit(&xml, " </host>\n\n");
diff -up libvirt-0.6.0/src/capabilities.h.svirt libvirt-0.6.0/src/capabilities.h
--- libvirt-0.6.0/src/capabilities.h.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/capabilities.h 2009-02-17 10:07:06.292677000 -0500
@@ -78,6 +78,12 @@ struct _virCapsHostNUMACell {
int *cpus;
};
+typedef struct _virCapsHostSecModel virCapsHostSecModel;
+struct _virCapsHostSecModel {
+ char *model;
+ char *doi;
+};
+
typedef struct _virCapsHost virCapsHost;
typedef virCapsHost *virCapsHostPtr;
struct _virCapsHost {
@@ -90,6 +96,7 @@ struct _virCapsHost {
char **migrateTrans;
int nnumaCell;
virCapsHostNUMACellPtr *numaCell;
+ virCapsHostSecModel secModel;
};
typedef struct _virCaps virCaps;
diff -up libvirt-0.6.0/src/domain_conf.c.svirt libvirt-0.6.0/src/domain_conf.c
--- libvirt-0.6.0/src/domain_conf.c.svirt 2009-02-17 10:07:06.195708000 -0500
+++ libvirt-0.6.0/src/domain_conf.c 2009-02-17 10:07:06.300677000 -0500
@@ -379,6 +379,16 @@ void virDomainDeviceDefFree(virDomainDev
VIR_FREE(def);
}
+void virSecurityLabelDefFree(virDomainDefPtr def);
+
+void virSecurityLabelDefFree(virDomainDefPtr def)
+{
+ if (def->seclabel.model)
+ VIR_FREE(def->seclabel.model);
+ if (def->seclabel.label)
+ VIR_FREE(def->seclabel.label);
+}
+
void virDomainDefFree(virDomainDefPtr def)
{
unsigned int i;
@@ -437,6 +447,8 @@ void virDomainDefFree(virDomainDefPtr de
VIR_FREE(def->cpumask);
VIR_FREE(def->emulator);
+ virSecurityLabelDefFree(def);
+
VIR_FREE(def);
}
@@ -1818,6 +1830,34 @@ static int virDomainLifecycleParseXML(vi
return 0;
}
+static int
+virSecurityLabelDefParseXML(virConnectPtr conn,
+ const virDomainDefPtr def,
+ xmlXPathContextPtr ctxt)
+{
+ char *p;
+
+ if (virXPathNode(conn, "./seclabel", ctxt) == NULL)
+ return 0;
+
+ p = virXPathStringLimit(conn, "string(./seclabel/label[1])",
+ VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
+ if (p == NULL)
+ goto error;
+ def->seclabel.label = p;
+
+ p = virXPathStringLimit(conn, "string(./seclabel/@model)",
+ VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
+ if (p == NULL)
+ goto error;
+ def->seclabel.model = p;
+
+ return 0;
+
+error:
+ virSecurityLabelDefFree(def);
+ return -1;
+}
virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn,
virCapsPtr caps,
@@ -2403,6 +2443,10 @@ static virDomainDefPtr virDomainDefParse
}
VIR_FREE(nodes);
+ /* analysis of security label */
+ if (virSecurityLabelDefParseXML(conn, def, ctxt) == -1)
+ goto error;
+
return def;
no_memory:
@@ -3420,6 +3464,13 @@ char *virDomainDefFormat(virConnectPtr c
goto cleanup;
virBufferAddLit(&buf, " </devices>\n");
+
+ if (def->seclabel.model) {
+ virBufferEscapeString(&buf, " <seclabel
model='%s'>\n", def->seclabel.model);
+ virBufferEscapeString(&buf, " <label>%s</label>\n",
def->seclabel.label);
+ virBufferAddLit(&buf, " </seclabel>\n");
+ }
+
virBufferAddLit(&buf, "</domain>\n");
if (virBufferError(&buf))
diff -up libvirt-0.6.0/src/domain_conf.h.svirt libvirt-0.6.0/src/domain_conf.h
--- libvirt-0.6.0/src/domain_conf.h.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/domain_conf.h 2009-02-17 10:07:06.307676000 -0500
@@ -407,6 +407,14 @@ struct _virDomainOSDef {
char *bootloaderArgs;
};
+/* Security configuration for domain */
+typedef struct _virSecurityLabelDef virSecurityLabelDef;
+typedef virSecurityLabelDef *virSecurityLabelDefPtr;
+struct _virSecurityLabelDef {
+ char *model; /* name of security model */
+ char *label; /* security label string */
+};
+
#define VIR_DOMAIN_CPUMASK_LEN 1024
/* Guest VM main configuration */
@@ -464,6 +472,7 @@ struct _virDomainDef {
/* Only 1 */
virDomainChrDefPtr console;
+ virSecurityLabelDef seclabel;
};
/* Guest VM runtime state */
diff -up libvirt-0.6.0/src/driver.h.svirt libvirt-0.6.0/src/driver.h
--- libvirt-0.6.0/src/driver.h.svirt 2008-12-19 07:51:11.000000000 -0500
+++ libvirt-0.6.0/src/driver.h 2009-02-17 10:07:06.313676000 -0500
@@ -181,6 +181,12 @@ typedef int
typedef int
(*virDrvDomainGetMaxVcpus) (virDomainPtr domain);
typedef int
+ (*virDrvDomainGetSecurityLabel) (virDomainPtr domain,
+ virSecurityLabelPtr seclabel);
+typedef int
+ (*virDrvNodeGetSecurityModel) (virConnectPtr conn,
+ virSecurityModelPtr secmodel);
+typedef int
(*virDrvDomainAttachDevice) (virDomainPtr domain,
const char *xml);
typedef int
@@ -361,6 +367,8 @@ struct _virDriver {
virDrvDomainPinVcpu domainPinVcpu;
virDrvDomainGetVcpus domainGetVcpus;
virDrvDomainGetMaxVcpus domainGetMaxVcpus;
+ virDrvDomainGetSecurityLabel domainGetSecurityLabel;
+ virDrvNodeGetSecurityModel nodeGetSecurityModel;
virDrvDomainDumpXML domainDumpXML;
virDrvListDefinedDomains listDefinedDomains;
virDrvNumOfDefinedDomains numOfDefinedDomains;
diff -up libvirt-0.6.0/src/libvirt.c.svirt libvirt-0.6.0/src/libvirt.c
--- libvirt-0.6.0/src/libvirt.c.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/libvirt.c 2009-02-17 10:07:06.332683000 -0500
@@ -4156,6 +4156,70 @@ error:
return -1;
}
+/**
+ * virDomainGetSecurityLabel:
+ * @domain: a domain object
+ * @seclabel: pointer to a virSecurityLabel structure
+ *
+ * Extract security label of an active domain.
+ *
+ * Returns 0 in case of success, -1 in case of failure, and -2
+ * if the operation is not supported (caller decides if that's
+ * an error).
+ */
+int
+virDomainGetSecurityLabel(virDomainPtr domain, virSecurityLabelPtr seclabel)
+{
+ virConnectPtr conn;
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return -1;
+ }
+
+ if (seclabel == NULL) {
+ virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return -1;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetSecurityLabel)
+ return conn->driver->domainGetSecurityLabel(domain, seclabel);
+
+ virLibConnWarning(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -2;
+}
+
+/**
+ * virNodeGetSecurityModel:
+ * @conn: a connection object
+ * @secmodel: pointer to a virSecurityModel structure
+ *
+ * Extract the security model of a hypervisor.
+ *
+ * Returns 0 in case of success, -1 in case of failure, and -2 if the
+ * operation is not supported (caller decides if that's an error).
+ */
+int
+virNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
+{
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return -1;
+ }
+
+ if (secmodel == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return -1;
+ }
+
+ if (conn->driver->nodeGetSecurityModel)
+ return conn->driver->nodeGetSecurityModel(conn, secmodel);
+
+ virLibConnWarning(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -2;
+}
/**
* virDomainAttachDevice:
diff -up libvirt-0.6.0/src/libvirt_private.syms.svirt
libvirt-0.6.0/src/libvirt_private.syms
--- libvirt-0.6.0/src/libvirt_private.syms.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/libvirt_private.syms 2009-02-17 10:36:52.867582000 -0500
@@ -334,3 +334,4 @@ virXPathNode;
virXPathNodeSet;
virXPathString;
virXMLPropString;
+virXPathStringLimit;
diff -up libvirt-0.6.0/src/libvirt_public.syms.svirt
libvirt-0.6.0/src/libvirt_public.syms
--- libvirt-0.6.0/src/libvirt_public.syms.svirt 2009-01-20 08:48:28.000000000 -0500
+++ libvirt-0.6.0/src/libvirt_public.syms 2009-02-17 10:37:09.630287000 -0500
@@ -244,7 +244,8 @@ LIBVIRT_0.6.0 {
virStoragePoolRef;
virStorageVolRef;
virNodeDeviceRef;
-
+ virDomainGetSecurityLabel;
+ virNodeGetSecurityModel;
} LIBVIRT_0.5.0;
# .... define new API here using predicted next version number ....
diff -up libvirt-0.6.0/src/lxc_driver.c.svirt libvirt-0.6.0/src/lxc_driver.c
--- libvirt-0.6.0/src/lxc_driver.c.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/lxc_driver.c 2009-02-17 10:07:06.339677000 -0500
@@ -1430,6 +1430,8 @@ static virDriver lxcDriver = {
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel */
+ NULL, /* nodeGetSecurityModel */
lxcDomainDumpXML, /* domainDumpXML */
lxcListDefinedDomains, /* listDefinedDomains */
lxcNumDefinedDomains, /* numOfDefinedDomains */
diff -up libvirt-0.6.0/src/Makefile.am.svirt libvirt-0.6.0/src/Makefile.am
--- libvirt-0.6.0/src/Makefile.am.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/Makefile.am 2009-02-17 10:07:06.346676000 -0500
@@ -139,7 +139,7 @@ UML_DRIVER_SOURCES = \
NETWORK_DRIVER_SOURCES = \
network_driver.h network_driver.c
-# And finally storage backend specific impls
+# Storage backend specific impls
STORAGE_DRIVER_SOURCES = \
storage_driver.h storage_driver.c \
storage_backend.h storage_backend.c
@@ -164,6 +164,12 @@ STORAGE_DRIVER_DISK_SOURCES = \
STORAGE_HELPER_DISK_SOURCES = \
parthelper.c
+# Security framework and drivers for various models
+SECURITY_DRIVER_SOURCES = \
+ security.h security.c
+
+SECURITY_DRIVER_SELINUX_SOURCES = \
+ security_selinux.h security_selinux.c
NODE_DEVICE_DRIVER_SOURCES = \
node_device.c node_device.h
@@ -377,6 +383,19 @@ libvirt_driver_nodedev_la_LDFLAGS += -mo
endif
endif
+libvirt_driver_security_la_SOURCES = $(SECURITY_DRIVER_SOURCES)
+if WITH_DRIVER_MODULES
+mod_LTLIBRARIES += libvirt_driver_security.la
+else
+noinst_LTLIBRARIES += libvirt_driver_security.la
+endif
+if WITH_DRIVER_MODULES
+libvirt_driver_security_la_LDFLAGS = -module -avoid-version
+endif
+
+if HAVE_SELINUX
+libvirt_driver_security_la_SOURCES += $(SECURITY_DRIVER_SELINUX_SOURCES)
+endif
# Add all conditional sources just in case...
EXTRA_DIST += \
@@ -395,7 +414,9 @@ EXTRA_DIST += \
$(STORAGE_DRIVER_DISK_SOURCES) \
$(NODE_DEVICE_DRIVER_SOURCES) \
$(NODE_DEVICE_DRIVER_HAL_SOURCES) \
- $(NODE_DEVICE_DRIVER_DEVKIT_SOURCES)
+ $(NODE_DEVICE_DRIVER_DEVKIT_SOURCES) \
+ $(SECURITY_DRIVER_SOURCES) \
+ $(SECURITY_DRIVER_SELINUX_SOURCES)
#
# Build our version script. This is composed of three parts:
diff -up libvirt-0.6.0/src/openvz_driver.c.svirt libvirt-0.6.0/src/openvz_driver.c
--- libvirt-0.6.0/src/openvz_driver.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/openvz_driver.c 2009-02-17 10:07:06.362676000 -0500
@@ -1299,6 +1299,8 @@ static virDriver openvzDriver = {
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel */
+ NULL, /* nodeGetSecurityModel */
openvzDomainDumpXML, /* domainDumpXML */
openvzListDefinedDomains, /* listDomains */
openvzNumDefinedDomains, /* numOfDomains */
diff -up libvirt-0.6.0/src/qemu_conf.h.svirt libvirt-0.6.0/src/qemu_conf.h
--- libvirt-0.6.0/src/qemu_conf.h.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/qemu_conf.h 2009-02-17 10:07:06.368680000 -0500
@@ -33,6 +33,7 @@
#include "domain_conf.h"
#include "domain_event.h"
#include "threads.h"
+#include "security.h"
#define qemudDebug(fmt, ...) do {} while(0)
@@ -83,6 +84,8 @@ struct qemud_driver {
virDomainEventQueuePtr domainEventQueue;
int domainEventTimer;
int domainEventDispatching;
+
+ virSecurityDriverPtr securityDriver;
};
/* Status needed to reconenct to running VMs */
diff -up libvirt-0.6.0/src/qemu_driver.c.svirt libvirt-0.6.0/src/qemu_driver.c
--- libvirt-0.6.0/src/qemu_driver.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/qemu_driver.c 2009-02-17 10:07:06.378682000 -0500
@@ -68,6 +68,7 @@
#include "memory.h"
#include "uuid.h"
#include "domain_conf.h"
+#include "security.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -383,6 +384,50 @@ next:
return 0;
}
+static int
+qemudSecurityInit(struct qemud_driver *qemud_drv)
+{
+ int ret;
+ const char *doi, *model;
+ virCapsPtr caps;
+ virSecurityDriverPtr security_drv;
+
+ ret = virSecurityDriverStartup(&security_drv);
+ if (ret == -1) {
+ qemudLog(QEMUD_ERR, _("Failed to start security driver"));
+ return -1;
+ }
+ /* No security driver wanted to be enabled: just return */
+ if (ret == -2)
+ return 0;
+
+ qemud_drv->securityDriver = security_drv;
+ doi = virSecurityDriverGetDOI(security_drv);
+ model = virSecurityDriverGetModel(security_drv);
+
+ qemudLog(QEMUD_DEBUG, "Initialized security driver \"%s\" with "
+ "DOI \"%s\".\n", model, doi);
+
+ /*
+ * Add security policy host caps now that the security driver is
+ * initialized.
+ */
+ caps = qemud_drv->caps;
+
+ caps->host.secModel.model = strdup(model);
+ if (!caps->host.secModel.model) {
+ qemudLog(QEMUD_ERR, _("Failed to copy secModel model: %s"),
strerror(errno));
+ return -1;
+ }
+
+ caps->host.secModel.doi = strdup(doi);
+ if (!caps->host.secModel.doi) {
+ qemudLog(QEMUD_ERR, _("Failed to copy secModel DOI: %s"),
strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
/**
* qemudStartup:
@@ -474,6 +519,11 @@ qemudStartup(void) {
if ((qemu_driver->caps = qemudCapsInit()) == NULL)
goto out_of_memory;
+ if (qemudSecurityInit(qemu_driver) < 0) {
+ qemudShutdown();
+ return -1;
+ }
+
if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) {
goto error;
}
@@ -1111,6 +1161,15 @@ static int qemudNextFreeVNCPort(struct q
return -1;
}
+static int qemudDomainSetSecurityLabel(virConnectPtr conn, struct qemud_driver *driver,
virDomainObjPtr vm)
+{
+ if (vm->def->seclabel.label != NULL)
+ if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityLabel)
+ return driver->securityDriver->domainSetSecurityLabel(conn,
driver->securityDriver,
+
&vm->def->seclabel);
+ return 0;
+}
+
static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
const char *name);
@@ -1178,6 +1237,16 @@ static int qemudStartVMDaemon(virConnect
return -1;
}
+ /*
+ * Set up the security label for the domain here, before doing
+ * too much else.
+ */
+ if (qemudDomainSetSecurityLabel(conn, driver, vm) < 0) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to set security label"));
+ return -1;
+ }
+
if (qemudExtractVersionInfo(emulator,
NULL,
&qemuCmdFlags) < 0) {
@@ -2721,7 +2790,94 @@ cleanup:
return ret;
}
+static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr seclabel)
+{
+ struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
+ virDomainObjPtr vm;
+ const char *type;
+ int ret = -1;
+
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+ _("no domain with matching uuid '%s'"),
uuidstr);
+ goto cleanup;
+ }
+
+ if (!(type = virDomainVirtTypeToString(vm->def->virtType))) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("unknown virt type in domain definition
'%d'"),
+ vm->def->virtType);
+ goto cleanup;
+ }
+
+ /*
+ * Theoretically, the pid can be replaced during this operation and
+ * return the label of a different process. If atomicity is needed,
+ * further validation will be required.
+ *
+ * Comment from Dan Berrange:
+ *
+ * Well the PID as stored in the virDomainObjPtr can't be changed
+ * because you've got a locked object. The OS level PID could have
+ * exited, though and in extreme circumstances have cycled through all
+ * PIDs back to ours. We could sanity check that our PID still exists
+ * after reading the label, by checking that our FD connecting to the
+ * QEMU monitor hasn't seen SIGHUP/ERR on poll().
+ */
+ if (virDomainIsActive(vm)) {
+ if (driver->securityDriver &&
driver->securityDriver->domainGetSecurityLabel) {
+ if (driver->securityDriver->domainGetSecurityLabel(dom->conn, vm,
seclabel) == -1) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to get security label"));
+ goto cleanup;
+ }
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ return ret;
+}
+
+static int qemudNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
+{
+ struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ char *p;
+
+ if (!driver->securityDriver)
+ return -2;
+
+ p = driver->caps->host.secModel.model;
+ if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("security model string exceeds max %d bytes"),
+ VIR_SECURITY_MODEL_BUFLEN-1);
+ return -1;
+ }
+ strcpy(secmodel->model, p);
+
+ p = driver->caps->host.secModel.doi;
+ if (strlen(p) >= VIR_SECURITY_DOI_BUFLEN-1) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("security DOI string exceeds max %d bytes"),
+ VIR_SECURITY_DOI_BUFLEN-1);
+ return -1;
+ }
+ strcpy(secmodel->doi, p);
+ return 0;
+}
+/* TODO: check seclabel restore */
static int qemudDomainRestore(virConnectPtr conn,
const char *path) {
struct qemud_driver *driver = conn->privateData;
@@ -4475,6 +4631,8 @@ static virDriver qemuDriver = {
NULL, /* domainGetVcpus */
#endif
qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */
+ qemudDomainGetSecurityLabel, /* domainGetSecurityLabel */
+ qemudNodeGetSecurityModel, /* nodeGetSecurityModel */
qemudDomainDumpXML, /* domainDumpXML */
qemudListDefinedDomains, /* listDomains */
qemudNumDefinedDomains, /* numOfDomains */
diff -up libvirt-0.6.0/src/remote_internal.c.svirt libvirt-0.6.0/src/remote_internal.c
--- libvirt-0.6.0/src/remote_internal.c.svirt 2009-02-17 10:07:06.207699000 -0500
+++ libvirt-0.6.0/src/remote_internal.c 2009-02-17 10:14:28.509959000 -0500
@@ -2299,6 +2299,67 @@ done:
return rv;
}
+static int
+remoteDomainGetSecurityLabel (virDomainPtr domain, virSecurityLabelPtr seclabel)
+{
+ remote_domain_get_security_label_args args;
+ remote_domain_get_security_label_ret ret;
+ struct private_data *priv = domain->conn->privateData;
+
+ make_nonnull_domain (&args.dom, domain);
+ memset (&ret, 0, sizeof ret);
+ if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL,
+ (xdrproc_t) xdr_remote_domain_get_security_label_args, (char *)&args,
+ (xdrproc_t) xdr_remote_domain_get_security_label_ret, (char *)&ret) ==
-1) {
+ return -1;
+ }
+
+ if (ret.label.label_val != NULL) {
+ if (strlen (ret.label.label_val) >= sizeof seclabel->label) {
+ errorf (domain->conn, VIR_ERR_RPC, _("security label exceeds maximum:
%zd"),
+ sizeof seclabel->label - 1);
+ return -1;
+ }
+ strcpy (seclabel->label, ret.label.label_val);
+ seclabel->enforcing = ret.enforcing;
+ }
+
+ return 0;
+}
+
+static int
+remoteNodeGetSecurityModel (virConnectPtr conn, virSecurityModelPtr secmodel)
+{
+ remote_node_get_security_model_ret ret;
+ struct private_data *priv = conn->privateData;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_SECURITY_MODEL,
+ (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_remote_node_get_security_model_ret, (char *)&ret) ==
-1) {
+ return -1;
+ }
+
+ if (ret.model.model_val != NULL) {
+ if (strlen (ret.model.model_val) >= sizeof secmodel->model) {
+ errorf (conn, VIR_ERR_RPC, _("security model exceeds maximum:
%zd"),
+ sizeof secmodel->model - 1);
+ return -1;
+ }
+ strcpy (secmodel->model, ret.model.model_val);
+ }
+
+ if (ret.doi.doi_val != NULL) {
+ if (strlen (ret.doi.doi_val) >= sizeof secmodel->doi) {
+ errorf (conn, VIR_ERR_RPC, _("security doi exceeds maximum: %zd"),
+ sizeof secmodel->doi - 1);
+ return -1;
+ }
+ strcpy (secmodel->doi, ret.doi.doi_val);
+ }
+ return 0;
+}
+
static char *
remoteDomainDumpXML (virDomainPtr domain, int flags)
{
@@ -6721,6 +6782,8 @@ static virDriver driver = {
.domainPinVcpu = remoteDomainPinVcpu,
.domainGetVcpus = remoteDomainGetVcpus,
.domainGetMaxVcpus = remoteDomainGetMaxVcpus,
+ .domainGetSecurityLabel = remoteDomainGetSecurityLabel,
+ .nodeGetSecurityModel = remoteNodeGetSecurityModel,
.domainDumpXML = remoteDomainDumpXML,
.listDefinedDomains = remoteListDefinedDomains,
.numOfDefinedDomains = remoteNumOfDefinedDomains,
diff -up /dev/null libvirt-0.6.0/src/security.c
--- /dev/null 2009-02-11 16:31:53.992012235 -0500
+++ libvirt-0.6.0/src/security.c 2009-02-17 10:07:06.396676000 -0500
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Authors:
+ * James Morris <jmorris(a)namei.org>
+ *
+ */
+#include <config.h>
+#include <string.h>
+
+#include "virterror_internal.h"
+
+#include "security.h"
+
+#if HAVE_SELINUX
+#include "security_selinux.h"
+#endif
+
+static virSecurityDriverStatus testSecurityDriverProbe(void)
+{
+ return SECURITY_DRIVER_DISABLE;
+}
+
+virSecurityDriver virTestSecurityDriver = {
+ .name = "test",
+ .probe = testSecurityDriverProbe,
+};
+
+static virSecurityDriverPtr security_drivers[] = {
+ &virTestSecurityDriver,
+#ifdef HAVE_SELINUX
+ &virSELinuxSecurityDriver,
+#endif
+};
+
+/*
+ * Probe each security driver: each should perform a test to see if it
+ * should be loaded, e.g. if the currently active host security mechanism
+ * matches. If the probe succeeds, initialize the driver and return it.
+ *
+ * Returns 0 on success, and -1 on error. If no security driver wanted to
+ * be enabled, then return -2 and let the caller determine what this really
+ * means.
+ */
+int
+virSecurityDriverStartup(virSecurityDriverPtr * drv)
+{
+ unsigned int i;
+
+ for (i = 0; i < (sizeof(security_drivers) / sizeof(security_drivers[0])); i++) {
+ virSecurityDriverPtr tmp = security_drivers[i];
+ virSecurityDriverStatus ret = tmp->probe();
+
+ switch (ret) {
+ case SECURITY_DRIVER_ENABLE:
+ virSecurityDriverInit(tmp);
+ if (tmp->open(NULL, tmp) == -1) {
+ return -1;
+ } else {
+ *drv = tmp;
+ return 0;
+ }
+ break;
+
+ case SECURITY_DRIVER_DISABLE:
+ break;
+
+ default:
+ return -1;
+ }
+ }
+ return -2;
+}
+
+void
+virSecurityReportError(virConnectPtr conn, int code, const char *fmt, ...)
+{
+ va_list args;
+ char errorMessage[1024];
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(errorMessage, sizeof(errorMessage) - 1, fmt, args);
+ va_end(args);
+ } else
+ errorMessage[0] = '\0';
+
+ virRaiseError(conn, NULL, NULL, VIR_FROM_SECURITY, code,
+ VIR_ERR_ERROR, NULL, NULL, NULL, -1, -1, "%s",
+ errorMessage);
+}
+
+/*
+ * Helpers
+ */
+void
+virSecurityDriverInit(virSecurityDriverPtr drv)
+{
+ memset(&drv->_private, 0, sizeof drv->_private);
+}
+
+int
+virSecurityDriverSetDOI(virConnectPtr conn,
+ virSecurityDriverPtr drv,
+ const char *doi)
+{
+ if (strlen(doi) >= VIR_SECURITY_DOI_BUFLEN) {
+ virSecurityReportError(conn, VIR_ERR_ERROR,
+ _("%s: DOI \'%s\' is "
+ "longer than the maximum allowed length of
%d"),
+ __func__, doi, VIR_SECURITY_DOI_BUFLEN - 1);
+ return -1;
+ }
+ strcpy(drv->_private.doi, doi);
+ return 0;
+}
+
+const char *
+virSecurityDriverGetDOI(virSecurityDriverPtr drv)
+{
+ return drv->_private.doi;
+}
+
+const char *
+virSecurityDriverGetModel(virSecurityDriverPtr drv)
+{
+ return drv->name;
+}
diff -up /dev/null libvirt-0.6.0/src/security.h
--- /dev/null 2009-02-11 16:31:53.992012235 -0500
+++ libvirt-0.6.0/src/security.h 2009-02-17 10:07:06.402676000 -0500
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Authors:
+ * James Morris <jmorris(a)namei.org>
+ *
+ */
+#ifndef __VIR_SECURITY_H__
+#define __VIR_SECURITY_H__
+
+#include "internal.h"
+#include "domain_conf.h"
+
+/*
+ * Return values for security driver probing: the driver will determine
+ * whether it should be enabled or disabled.
+ */
+typedef enum {
+ SECURITY_DRIVER_ENABLE = 0,
+ SECURITY_DRIVER_ERROR = -1,
+ SECURITY_DRIVER_DISABLE = -2,
+} virSecurityDriverStatus;
+
+typedef struct _virSecurityDriver virSecurityDriver;
+typedef virSecurityDriver *virSecurityDriverPtr;
+typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
+typedef int (*virSecurityDriverOpen) (virConnectPtr conn,
+ virSecurityDriverPtr drv);
+typedef int (*virSecurityDomainGetLabel) (virConnectPtr conn,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr sec);
+typedef int (*virSecurityDomainSetLabel) (virConnectPtr conn,
+ virSecurityDriverPtr drv,
+ virSecurityLabelDefPtr secdef);
+
+struct _virSecurityDriver {
+ const char *name;
+ virSecurityDriverProbe probe;
+ virSecurityDriverOpen open;
+ virSecurityDomainGetLabel domainGetSecurityLabel;
+ virSecurityDomainSetLabel domainSetSecurityLabel;
+
+ /*
+ * This is internally managed driver state and should only be accessed
+ * via helpers below.
+ */
+ struct {
+ char doi[VIR_SECURITY_DOI_BUFLEN];
+ } _private;
+};
+
+/* Global methods */
+int virSecurityDriverStartup(virSecurityDriverPtr * drv);
+
+void
+virSecurityReportError(virConnectPtr conn, int code, const char *fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 3, 4);
+
+/* Helpers */
+void virSecurityDriverInit(virSecurityDriverPtr drv);
+int virSecurityDriverSetDOI(virConnectPtr conn,
+ virSecurityDriverPtr drv,
+ const char *doi);
+const char *virSecurityDriverGetDOI(virSecurityDriverPtr drv);
+const char *virSecurityDriverGetModel(virSecurityDriverPtr drv);
+
+#endif /* __VIR_SECURITY_H__ */
diff -up /dev/null libvirt-0.6.0/src/security_selinux.c
--- /dev/null 2009-02-11 16:31:53.992012235 -0500
+++ libvirt-0.6.0/src/security_selinux.c 2009-02-17 10:07:06.407678000 -0500
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Authors:
+ * James Morris <jmorris(a)namei.org>
+ *
+ * SELinux security driver.
+ */
+#include <config.h>
+#include <selinux/selinux.h>
+
+#include "security.h"
+#include "security_selinux.h"
+
+#define SECURITY_SELINUX_VOID_DOI "0"
+
+static int
+SELinuxSecurityDriverProbe(void)
+{
+ return is_selinux_enabled() ? SECURITY_DRIVER_ENABLE : SECURITY_DRIVER_DISABLE;
+}
+
+static int
+SELinuxSecurityDriverOpen(virConnectPtr conn, virSecurityDriverPtr drv)
+{
+ /*
+ * Where will the DOI come from? SELinux configuration, or qemu
+ * configuration? For the moment, we'll just set it to "0".
+ */
+ virSecurityDriverSetDOI(conn, drv, SECURITY_SELINUX_VOID_DOI);
+
+ return 0;
+}
+
+static int
+SELinuxSecurityDomainGetSecurityLabel(virConnectPtr conn,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr sec)
+{
+ security_context_t ctx;
+
+ if (getpidcon(vm->pid, &ctx) == -1) {
+ virSecurityReportError(conn, VIR_ERR_ERROR, _("%s: error calling "
+ "getpidcon(): %s"), __func__,
+ strerror(errno));
+ return -1;
+ }
+
+ if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) {
+ virSecurityReportError(conn, VIR_ERR_ERROR,
+ _("%s: security label exceeds "
+ "maximum length: %d"), __func__,
+ VIR_SECURITY_LABEL_BUFLEN - 1);
+ return -1;
+ }
+
+ strcpy(sec->label, (char *) ctx);
+ free(ctx);
+
+ sec->enforcing = security_getenforce();
+ if (sec->enforcing == -1) {
+ virSecurityReportError(conn, VIR_ERR_ERROR, _("%s: error calling "
+ "security_getenforce(): %s"), __func__,
+ strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+SELinuxSecurityDomainSetSecurityLabel(virConnectPtr conn,
+ virSecurityDriverPtr drv,
+ const virSecurityLabelDefPtr secdef)
+{
+ /* TODO: verify DOI */
+
+ if (!STREQ(drv->name, secdef->model)) {
+ virSecurityReportError(conn, VIR_ERR_ERROR,
+ _("%s: security label driver mismatch: "
+ "\'%s\' model configured for domain, but
"
+ "hypervisor driver is \'%s\'."),
+ __func__, secdef->model, drv->name);
+ return -1;
+ }
+
+ if (setexeccon(secdef->label) == -1) {
+ virSecurityReportError(conn, VIR_ERR_ERROR,
+ _("%s: unable to set security context "
+ "'\%s\': %s."), __func__,
secdef->label,
+ strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+virSecurityDriver virSELinuxSecurityDriver = {
+ .name = "selinux",
+ .probe = SELinuxSecurityDriverProbe,
+ .open = SELinuxSecurityDriverOpen,
+ .domainGetSecurityLabel = SELinuxSecurityDomainGetSecurityLabel,
+ .domainSetSecurityLabel = SELinuxSecurityDomainSetSecurityLabel,
+};
diff -up /dev/null libvirt-0.6.0/src/security_selinux.h
--- /dev/null 2009-02-11 16:31:53.992012235 -0500
+++ libvirt-0.6.0/src/security_selinux.h 2009-02-17 10:07:06.413677000 -0500
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Authors:
+ * James Morris <jmorris(a)namei.org>
+ *
+ */
+#ifndef __VIR_SECURITY_SELINUX_H__
+#define __VIR_SECURITY_SELINUX_H__
+
+extern virSecurityDriver virSELinuxSecurityDriver;
+
+#endif /* __VIR_SECURITY_SELINUX_H__ */
diff -up libvirt-0.6.0/src/storage_backend.c.svirt libvirt-0.6.0/src/storage_backend.c
--- libvirt-0.6.0/src/storage_backend.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/storage_backend.c 2009-02-17 10:07:06.419677000 -0500
@@ -276,6 +276,7 @@ virStorageBackendUpdateVolTargetInfoFD(v
VIR_FREE(target->perms.label);
#if HAVE_SELINUX
+ /* XXX: make this a security driver call */
if (fgetfilecon(fd, &filecon) == -1) {
if (errno != ENODATA && errno != ENOTSUP) {
virReportSystemError(conn, errno,
diff -up libvirt-0.6.0/src/test.c.svirt libvirt-0.6.0/src/test.c
--- libvirt-0.6.0/src/test.c.svirt 2009-01-20 15:39:28.000000000 -0500
+++ libvirt-0.6.0/src/test.c 2009-02-17 10:07:06.428677000 -0500
@@ -3510,6 +3510,8 @@ static virDriver testDriver = {
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel */
+ NULL, /* nodeGetSecurityModel */
testDomainDumpXML, /* domainDumpXML */
testListDefinedDomains, /* listDefinedDomains */
testNumOfDefinedDomains, /* numOfDefinedDomains */
diff -up libvirt-0.6.0/src/uml_driver.c.svirt libvirt-0.6.0/src/uml_driver.c
--- libvirt-0.6.0/src/uml_driver.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/uml_driver.c 2009-02-17 10:07:06.436676000 -0500
@@ -1852,6 +1852,8 @@ static virDriver umlDriver = {
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel */
+ NULL, /* nodeGetSecurityModel */
umlDomainDumpXML, /* domainDumpXML */
umlListDefinedDomains, /* listDomains */
umlNumDefinedDomains, /* numOfDomains */
diff -up libvirt-0.6.0/src/virsh.c.svirt libvirt-0.6.0/src/virsh.c
--- libvirt-0.6.0/src/virsh.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/virsh.c 2009-02-17 10:07:06.447677000 -0500
@@ -954,6 +954,7 @@ static const vshCmdOptDef opts_undefine[
{NULL, 0, 0, NULL}
};
+/* XXX MAC policy for defining & undefining domains ?? */
static int
cmdUndefine(vshControl *ctl, const vshCmd *cmd)
{
@@ -1515,6 +1516,8 @@ cmdDominfo(vshControl *ctl, const vshCmd
{
virDomainInfo info;
virDomainPtr dom;
+ virSecurityModel secmodel;
+ virSecurityLabel seclabel;
int ret = TRUE, autostart;
unsigned int id;
char *str, uuid[VIR_UUID_STRING_BUFLEN];
@@ -1573,6 +1576,29 @@ cmdDominfo(vshControl *ctl, const vshCmd
autostart ? _("enable") : _("disable") );
}
+ /* Security model and label information */
+ memset(&secmodel, 0, sizeof secmodel);
+ if (virNodeGetSecurityModel(ctl->conn, &secmodel) == -1) {
+ virDomainFree(dom);
+ return FALSE;
+ } else {
+ /* Only print something if a security model is active */
+ if (secmodel.model[0] != '\0') {
+ vshPrint(ctl, "%-15s %s\n", _("Security model:"),
secmodel.model);
+ vshPrint(ctl, "%-15s %s\n", _("Security DOI:"),
secmodel.doi);
+
+ /* Security labels are only valid for active domains */
+ memset(&seclabel, 0, sizeof seclabel);
+ if (virDomainGetSecurityLabel(dom, &seclabel) == -1) {
+ virDomainFree(dom);
+ return FALSE;
+ } else {
+ if (seclabel.label[0] != '\0')
+ vshPrint(ctl, "%-15s %s (%s)\n", _("Security
label:"),
+ seclabel.label, seclabel.enforcing ? "enforcing" :
"permissive");
+ }
+ }
+ }
virDomainFree(dom);
return ret;
}
diff -up libvirt-0.6.0/src/virterror.c.svirt libvirt-0.6.0/src/virterror.c
--- libvirt-0.6.0/src/virterror.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/virterror.c 2009-02-17 10:07:06.454684000 -0500
@@ -151,6 +151,9 @@ static const char *virErrorDomainName(vi
case VIR_FROM_UML:
dom = "UML ";
break;
+ case VIR_FROM_SECURITY:
+ dom = "Security Labeling ";
+ break;
}
return(dom);
}
@@ -962,6 +965,12 @@ virErrorMsg(virErrorNumber error, const
else
errmsg = _("Node device not found: %s");
break;
+ case VIR_ERR_NO_SECURITY_MODEL:
+ if (info == NULL)
+ errmsg = _("Security model not found");
+ else
+ errmsg = _("Security model not found: %s");
+ break;
}
return (errmsg);
}
diff -up libvirt-0.6.0/src/xml.c.svirt libvirt-0.6.0/src/xml.c
--- libvirt-0.6.0/src/xml.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/xml.c 2009-02-17 10:07:06.461676000 -0500
@@ -77,6 +77,39 @@ virXPathString(virConnectPtr conn,
}
/**
+ * virXPathStringLimit:
+ * @xpath: the XPath string to evaluate
+ * @maxlen: maximum length permittred string
+ * @ctxt: an XPath context
+ *
+ * Wrapper for virXPathString, which validates the length of the returned
+ * string.
+ *
+ * Returns a new string which must be deallocated by the caller or NULL if
+ * the evaluation failed.
+ */
+char *
+virXPathStringLimit(virConnectPtr conn,
+ const char *xpath,
+ size_t maxlen,
+ xmlXPathContextPtr ctxt)
+{
+ char *tmp = virXPathString(conn, xpath, ctxt);
+
+ if (tmp != NULL) {
+ if (strlen(tmp) >= maxlen) {
+ virXMLError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("\'%s\' value longer than %Zd bytes in
virXPathStringLimit()"),
+ xpath, maxlen);
+ return NULL;
+ }
+ } else
+ virXMLError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("\'%s\' missing in virXPathStringLimit()"),
xpath);
+ return tmp;
+}
+
+/**
* virXPathNumber:
* @xpath: the XPath string to evaluate
* @ctxt: an XPath context
diff -up libvirt-0.6.0/src/xml.h.svirt libvirt-0.6.0/src/xml.h
--- libvirt-0.6.0/src/xml.h.svirt 2008-08-12 03:13:00.000000000 -0400
+++ libvirt-0.6.0/src/xml.h 2009-02-17 10:07:06.467677000 -0500
@@ -17,6 +17,10 @@ int virXPathBoolean (virConnectPtr conn
char * virXPathString (virConnectPtr conn,
const char *xpath,
xmlXPathContextPtr ctxt);
+char * virXPathStringLimit(virConnectPtr conn,
+ const char *xpath,
+ size_t maxlen,
+ xmlXPathContextPtr ctxt);
int virXPathNumber (virConnectPtr conn,
const char *xpath,
xmlXPathContextPtr ctxt,
diff -up libvirt-0.6.0/tests/daemon-conf.svirt libvirt-0.6.0/tests/daemon-conf
--- libvirt-0.6.0/tests/daemon-conf.svirt 2008-12-22 08:21:49.000000000 -0500
+++ libvirt-0.6.0/tests/daemon-conf 2009-02-17 10:07:06.470678000 -0500
@@ -63,6 +63,9 @@ while :; do
-e '/^libnuma: Warning: .sys not mounted or no numa system/d' \
err > k && mv k err
+ # Filter out this diagnostic, too.
+ sed '/^Initialized security driver/d' err > k && mv k err
+
printf '%s\n\n' "remoteReadConfigFile: $f: $param_name: $msg" >
expected-err
diff -u expected-err err || fail=1