mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 15:27:47 +00:00
Re-add domain device seclabel parsing / formatting
This re-introduces parsing & formatting for per device seclabels. There is a new virDomainDeviceSeclabelPtr struct and corresponding APIs for parsing/formatting.
This commit is contained in:
parent
ae6135bf05
commit
87c39f0e20
@ -812,6 +812,17 @@ virSecurityLabelDefClear(virSecurityLabelDefPtr def)
|
|||||||
VIR_FREE(def->baselabel);
|
VIR_FREE(def->baselabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virSecurityDeviceLabelDefFree(virSecurityDeviceLabelDefPtr def)
|
||||||
|
{
|
||||||
|
if (!def)
|
||||||
|
return;
|
||||||
|
VIR_FREE(def->label);
|
||||||
|
VIR_FREE(def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
|
void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
|
||||||
{
|
{
|
||||||
int ii;
|
int ii;
|
||||||
@ -890,6 +901,8 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
|
|||||||
virStorageEncryptionFree(def->encryption);
|
virStorageEncryptionFree(def->encryption);
|
||||||
virDomainDeviceInfoClear(&def->info);
|
virDomainDeviceInfoClear(&def->info);
|
||||||
|
|
||||||
|
virSecurityDeviceLabelDefFree(def->seclabel);
|
||||||
|
|
||||||
for (i = 0 ; i < def->nhosts ; i++)
|
for (i = 0 ; i < def->nhosts ; i++)
|
||||||
virDomainDiskHostDefFree(&def->hosts[i]);
|
virDomainDiskHostDefFree(&def->hosts[i]);
|
||||||
VIR_FREE(def->hosts);
|
VIR_FREE(def->hosts);
|
||||||
@ -2666,6 +2679,67 @@ error:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr *def,
|
||||||
|
virSecurityLabelDefPtr vmDef,
|
||||||
|
xmlXPathContextPtr ctxt)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
*def = NULL;
|
||||||
|
|
||||||
|
if (virXPathNode("./seclabel", ctxt) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Can't use overrides if top-level doesn't allow relabeling. */
|
||||||
|
if (vmDef && vmDef->norelabel) {
|
||||||
|
virDomainReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("label overrides require relabeling to be "
|
||||||
|
"enabled at the domain level"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC(*def) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = virXPathStringLimit("string(./seclabel/@relabel)",
|
||||||
|
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
||||||
|
if (p != NULL) {
|
||||||
|
if (STREQ(p, "yes")) {
|
||||||
|
(*def)->norelabel = false;
|
||||||
|
} else if (STREQ(p, "no")) {
|
||||||
|
(*def)->norelabel = true;
|
||||||
|
} else {
|
||||||
|
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("invalid security relabel value %s"), p);
|
||||||
|
VIR_FREE(p);
|
||||||
|
VIR_FREE(*def);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
VIR_FREE(p);
|
||||||
|
} else {
|
||||||
|
(*def)->norelabel = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = virXPathStringLimit("string(./seclabel/label[1])",
|
||||||
|
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
||||||
|
(*def)->label = p;
|
||||||
|
|
||||||
|
if ((*def)->label && (*def)->norelabel) {
|
||||||
|
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("Cannot specify a label if relabelling is turned off"));
|
||||||
|
VIR_FREE((*def)->label);
|
||||||
|
VIR_FREE(*def);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse the XML definition for a lease
|
/* Parse the XML definition for a lease
|
||||||
*/
|
*/
|
||||||
static virDomainLeaseDefPtr
|
static virDomainLeaseDefPtr
|
||||||
@ -2747,9 +2821,11 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
xmlNodePtr node,
|
xmlNodePtr node,
|
||||||
xmlXPathContextPtr ctxt,
|
xmlXPathContextPtr ctxt,
|
||||||
virBitmapPtr bootMap,
|
virBitmapPtr bootMap,
|
||||||
|
virSecurityLabelDefPtr vmSeclabel,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
virDomainDiskDefPtr def;
|
virDomainDiskDefPtr def;
|
||||||
|
xmlNodePtr sourceNode = NULL;
|
||||||
xmlNodePtr cur, child;
|
xmlNodePtr cur, child;
|
||||||
xmlNodePtr save_ctxt = ctxt->node;
|
xmlNodePtr save_ctxt = ctxt->node;
|
||||||
char *type = NULL;
|
char *type = NULL;
|
||||||
@ -2808,6 +2884,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
if ((source == NULL && hosts == NULL) &&
|
if ((source == NULL && hosts == NULL) &&
|
||||||
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
||||||
|
|
||||||
|
sourceNode = cur;
|
||||||
|
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
case VIR_DOMAIN_DISK_TYPE_FILE:
|
case VIR_DOMAIN_DISK_TYPE_FILE:
|
||||||
source = virXMLPropString(cur, "file");
|
source = virXMLPropString(cur, "file");
|
||||||
@ -3057,6 +3135,17 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If source is present, check for an optional seclabel override. */
|
||||||
|
if (sourceNode) {
|
||||||
|
xmlNodePtr saved_node = ctxt->node;
|
||||||
|
ctxt->node = sourceNode;
|
||||||
|
if (virSecurityDeviceLabelDefParseXML(&def->seclabel,
|
||||||
|
vmSeclabel,
|
||||||
|
ctxt) < 0)
|
||||||
|
goto error;
|
||||||
|
ctxt->node = saved_node;
|
||||||
|
}
|
||||||
|
|
||||||
if (target == NULL) {
|
if (target == NULL) {
|
||||||
virDomainReportError(VIR_ERR_NO_TARGET,
|
virDomainReportError(VIR_ERR_NO_TARGET,
|
||||||
source ? "%s" : NULL, source);
|
source ? "%s" : NULL, source);
|
||||||
@ -6413,7 +6502,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
|
|||||||
if (xmlStrEqual(node->name, BAD_CAST "disk")) {
|
if (xmlStrEqual(node->name, BAD_CAST "disk")) {
|
||||||
dev->type = VIR_DOMAIN_DEVICE_DISK;
|
dev->type = VIR_DOMAIN_DEVICE_DISK;
|
||||||
if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, ctxt,
|
if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, ctxt,
|
||||||
NULL, flags)))
|
NULL, &def->seclabel, flags)))
|
||||||
goto error;
|
goto error;
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "lease")) {
|
} else if (xmlStrEqual(node->name, BAD_CAST "lease")) {
|
||||||
dev->type = VIR_DOMAIN_DEVICE_LEASE;
|
dev->type = VIR_DOMAIN_DEVICE_LEASE;
|
||||||
@ -7523,6 +7612,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
|
|||||||
nodes[i],
|
nodes[i],
|
||||||
ctxt,
|
ctxt,
|
||||||
bootMap,
|
bootMap,
|
||||||
|
&def->seclabel,
|
||||||
flags);
|
flags);
|
||||||
if (!disk)
|
if (!disk)
|
||||||
goto error;
|
goto error;
|
||||||
@ -9867,6 +9957,23 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virSecurityDeviceLabelDefFormat(virBufferPtr buf,
|
||||||
|
virSecurityDeviceLabelDefPtr def)
|
||||||
|
{
|
||||||
|
virBufferAsprintf(buf, "<seclabel relabel='%s'",
|
||||||
|
def->norelabel ? "no" : "yes");
|
||||||
|
if (def->label) {
|
||||||
|
virBufferAddLit(buf, ">\n");
|
||||||
|
virBufferEscapeString(buf, " <label>%s</label>\n",
|
||||||
|
def->label);
|
||||||
|
virBufferAddLit(buf, "</seclabel>\n");
|
||||||
|
} else {
|
||||||
|
virBufferAddLit(buf, "/>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virDomainLeaseDefFormat(virBufferPtr buf,
|
virDomainLeaseDefFormat(virBufferPtr buf,
|
||||||
virDomainLeaseDefPtr def)
|
virDomainLeaseDefPtr def)
|
||||||
@ -9989,17 +10096,34 @@ virDomainDiskDefFormat(virBufferPtr buf,
|
|||||||
def->startupPolicy) {
|
def->startupPolicy) {
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
case VIR_DOMAIN_DISK_TYPE_FILE:
|
case VIR_DOMAIN_DISK_TYPE_FILE:
|
||||||
virBufferAsprintf(buf," <source");
|
virBufferAddLit(buf," <source");
|
||||||
if (def->src)
|
if (def->src)
|
||||||
virBufferEscapeString(buf, " file='%s'", def->src);
|
virBufferEscapeString(buf, " file='%s'", def->src);
|
||||||
if (def->startupPolicy)
|
if (def->startupPolicy)
|
||||||
virBufferEscapeString(buf, " startupPolicy='%s'",
|
virBufferEscapeString(buf, " startupPolicy='%s'",
|
||||||
startupPolicy);
|
startupPolicy);
|
||||||
virBufferAsprintf(buf, "/>\n");
|
if (def->seclabel) {
|
||||||
|
virBufferAddLit(buf, ">\n");
|
||||||
|
virBufferAdjustIndent(buf, 8);
|
||||||
|
virSecurityDeviceLabelDefFormat(buf, def->seclabel);
|
||||||
|
virBufferAdjustIndent(buf, -8);
|
||||||
|
virBufferAddLit(buf, " </source>\n");
|
||||||
|
} else {
|
||||||
|
virBufferAddLit(buf, "/>\n");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_DISK_TYPE_BLOCK:
|
case VIR_DOMAIN_DISK_TYPE_BLOCK:
|
||||||
virBufferEscapeString(buf, " <source dev='%s'/>\n",
|
virBufferEscapeString(buf, " <source dev='%s'",
|
||||||
def->src);
|
def->src);
|
||||||
|
if (def->seclabel) {
|
||||||
|
virBufferAddLit(buf, ">\n");
|
||||||
|
virBufferAdjustIndent(buf, 8);
|
||||||
|
virSecurityDeviceLabelDefFormat(buf, def->seclabel);
|
||||||
|
virBufferAdjustIndent(buf, -8);
|
||||||
|
virBufferAddLit(buf, " </source>\n");
|
||||||
|
} else {
|
||||||
|
virBufferAddLit(buf, "/>\n");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_DISK_TYPE_DIR:
|
case VIR_DOMAIN_DISK_TYPE_DIR:
|
||||||
virBufferEscapeString(buf, " <source dir='%s'/>\n",
|
virBufferEscapeString(buf, " <source dir='%s'/>\n",
|
||||||
|
@ -193,6 +193,16 @@ struct _virSecurityLabelDef {
|
|||||||
bool norelabel;
|
bool norelabel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Security configuration for domain */
|
||||||
|
typedef struct _virSecurityDeviceLabelDef virSecurityDeviceLabelDef;
|
||||||
|
typedef virSecurityDeviceLabelDef *virSecurityDeviceLabelDefPtr;
|
||||||
|
struct _virSecurityDeviceLabelDef {
|
||||||
|
char *label; /* image label string */
|
||||||
|
bool norelabel;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct _virDomainHostdevOrigStates virDomainHostdevOrigStates;
|
typedef struct _virDomainHostdevOrigStates virDomainHostdevOrigStates;
|
||||||
typedef virDomainHostdevOrigStates *virDomainHostdevOrigStatesPtr;
|
typedef virDomainHostdevOrigStates *virDomainHostdevOrigStatesPtr;
|
||||||
struct _virDomainHostdevOrigStates {
|
struct _virDomainHostdevOrigStates {
|
||||||
@ -380,7 +390,7 @@ struct _virDomainDiskDef {
|
|||||||
int device;
|
int device;
|
||||||
int bus;
|
int bus;
|
||||||
char *src;
|
char *src;
|
||||||
virSecurityLabelDefPtr seclabel;
|
virSecurityDeviceLabelDefPtr seclabel;
|
||||||
char *dst;
|
char *dst;
|
||||||
int protocol;
|
int protocol;
|
||||||
int nhosts;
|
int nhosts;
|
||||||
|
Loading…
Reference in New Issue
Block a user