From 1c36b944e2bbf5efca30b3256c1c757ffb331395 Mon Sep 17 00:00:00 2001 From: John Ferlan Date: Mon, 23 Jun 2014 10:40:49 -0400 Subject: [PATCH] virstorage: Introduce virStorageAuthDef Introduce virStorageAuthDef and friends. Future patches will merge/utilize their view of storage source/pool auth/secret definitions. New API's include: virStorageAuthDefParse: Parse the "" XML data for either the domain disk or storage pool returning a virStorageAuthDefPtr virStorageAuthDefCopy: Copy a virStorageAuthDefPtr - to be used by the qemuTranslateDiskSourcePoolAuth when it copies storage pool auth data into domain disk auth data virStorageAuthDefFormat: Common output of the " #include #include "viralloc.h" +#include "virxml.h" +#include "viruuid.h" #include "virerror.h" #include "virlog.h" #include "virfile.h" @@ -97,6 +99,10 @@ VIR_ENUM_IMPL(virStorageSourcePoolMode, "host", "direct") +VIR_ENUM_IMPL(virStorageAuth, + VIR_STORAGE_AUTH_TYPE_LAST, + "none", "chap", "ceph") + enum lv_endian { LV_LITTLE_ENDIAN = 1, /* 1234 */ LV_BIG_ENDIAN /* 4321 */ @@ -1500,6 +1506,204 @@ virStorageNetHostDefCopy(size_t nhosts, } +void +virStorageAuthDefFree(virStorageAuthDefPtr authdef) +{ + if (!authdef) + return; + + VIR_FREE(authdef->username); + VIR_FREE(authdef->secrettype); + if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_USAGE) + VIR_FREE(authdef->secret.usage); + VIR_FREE(authdef); +} + + +virStorageAuthDefPtr +virStorageAuthDefCopy(const virStorageAuthDef *src) +{ + virStorageAuthDefPtr ret; + + if (VIR_ALLOC(ret) < 0) + return NULL; + + if (VIR_STRDUP(ret->username, src->username) < 0) + goto error; + /* Not present for storage pool, but used for disk source */ + if (VIR_STRDUP(ret->secrettype, src->secrettype) < 0) + goto error; + ret->authType = src->authType; + ret->secretType = src->secretType; + if (ret->secretType == VIR_STORAGE_SECRET_TYPE_UUID) { + memcpy(ret->secret.uuid, src->secret.uuid, sizeof(ret->secret.uuid)); + } else if (ret->secretType == VIR_STORAGE_SECRET_TYPE_USAGE) { + if (VIR_STRDUP(ret->secret.usage, src->secret.usage) < 0) + goto error; + } + return ret; + + error: + virStorageAuthDefFree(ret); + return NULL; +} + + +static int +virStorageAuthDefParseSecret(xmlXPathContextPtr ctxt, + virStorageAuthDefPtr authdef) +{ + char *uuid; + char *usage; + int ret = -1; + + /* Used by the domain disk xml parsing in order to ensure the + * secrettype = virXPathString("string(./secret/@type)", ctxt); + + uuid = virXPathString("string(./secret/@uuid)", ctxt); + usage = virXPathString("string(./secret/@usage)", ctxt); + if (uuid == NULL && usage == NULL) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing auth secret uuid or usage attribute")); + goto cleanup; + } + + if (uuid && usage) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("either auth secret uuid or usage expected")); + goto cleanup; + } + + if (uuid) { + if (virUUIDParse(uuid, authdef->secret.uuid) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("invalid auth secret uuid")); + goto cleanup; + } + authdef->secretType = VIR_STORAGE_SECRET_TYPE_UUID; + } else { + authdef->secret.usage = usage; + usage = NULL; + authdef->secretType = VIR_STORAGE_SECRET_TYPE_USAGE; + } + ret = 0; + + cleanup: + VIR_FREE(uuid); + VIR_FREE(usage); + return ret; +} + + +static virStorageAuthDefPtr +virStorageAuthDefParseXML(xmlXPathContextPtr ctxt) +{ + virStorageAuthDefPtr authdef = NULL; + char *username = NULL; + char *authtype = NULL; + + if (VIR_ALLOC(authdef) < 0) + return NULL; + + if (!(username = virXPathString("string(./@username)", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing username for auth")); + goto error; + } + authdef->username = username; + username = NULL; + + authdef->authType = VIR_STORAGE_AUTH_TYPE_NONE; + authtype = virXPathString("string(./@type)", ctxt); + if (authtype) { + /* Used by the storage pool instead of the secret type field + * to define whether chap or ceph being used + */ + if ((authdef->authType = virStorageAuthTypeFromString(authtype)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown auth type '%s'"), authtype); + goto error; + } + VIR_FREE(authtype); + } + + authdef->secretType = VIR_STORAGE_SECRET_TYPE_NONE; + if (virStorageAuthDefParseSecret(ctxt, authdef) < 0) + goto error; + + return authdef; + + error: + VIR_FREE(authtype); + VIR_FREE(username); + virStorageAuthDefFree(authdef); + return NULL; +} + + +virStorageAuthDefPtr +virStorageAuthDefParse(xmlDocPtr xml, xmlNodePtr root) +{ + xmlXPathContextPtr ctxt = NULL; + virStorageAuthDefPtr authdef = NULL; + + ctxt = xmlXPathNewContext(xml); + if (ctxt == NULL) { + virReportOOMError(); + goto cleanup; + } + + ctxt->node = root; + authdef = virStorageAuthDefParseXML(ctxt); + + cleanup: + xmlXPathFreeContext(ctxt); + return authdef; +} + + +int +virStorageAuthDefFormat(virBufferPtr buf, + virStorageAuthDefPtr authdef) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + + if (authdef->authType == VIR_STORAGE_AUTH_TYPE_NONE) { + virBufferEscapeString(buf, "\n", authdef->username); + } else { + virBufferAsprintf(buf, "authType)); + virBufferEscapeString(buf, "username='%s'>\n", authdef->username); + } + + virBufferAdjustIndent(buf, 2); + if (authdef->secrettype) + virBufferAsprintf(buf, "secrettype); + else + virBufferAddLit(buf, "secretType == VIR_STORAGE_SECRET_TYPE_UUID) { + virUUIDFormat(authdef->secret.uuid, uuidstr); + virBufferAsprintf(buf, " uuid='%s'/>\n", uuidstr); + } else if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_USAGE) { + virBufferEscapeString(buf, " usage='%s'/>\n", + authdef->secret.usage); + } else { + virBufferAddLit(buf, "/>\n"); + } + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + + return 0; +} + + virSecurityDeviceLabelDefPtr virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src, const char *model) diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 48c7e02b5..383ba96cb 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -192,6 +192,15 @@ struct _virStorageSourcePoolDef { typedef virStorageSourcePoolDef *virStorageSourcePoolDefPtr; +typedef enum { + VIR_STORAGE_AUTH_TYPE_NONE, + VIR_STORAGE_AUTH_TYPE_CHAP, + VIR_STORAGE_AUTH_TYPE_CEPHX, + + VIR_STORAGE_AUTH_TYPE_LAST, +} virStorageAuthType; +VIR_ENUM_DECL(virStorageAuth) + typedef enum { VIR_STORAGE_SECRET_TYPE_NONE, VIR_STORAGE_SECRET_TYPE_UUID, @@ -200,6 +209,19 @@ typedef enum { VIR_STORAGE_SECRET_TYPE_LAST } virStorageSecretType; +typedef struct _virStorageAuthDef virStorageAuthDef; +typedef virStorageAuthDef *virStorageAuthDefPtr; +struct _virStorageAuthDef { + char *username; + char *secrettype; /*