From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> --- include/libvirt/libvirt.h.in | 30 +++++++ include/libvirt/virterror.h | 1 + src/datatypes.h | 22 +++++- src/libvirt.c | 176 ++++++++++++++++++++++++++++++++++++++++++ src/util/virterror.c | 6 ++ 5 files changed, 234 insertions(+), 1 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index e436f3c..967a925 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1020,6 +1020,36 @@ typedef virConnectAuth *virConnectAuthPtr; VIR_EXPORT_VAR virConnectAuthPtr virConnectAuthPtrDefault; +typedef struct _virIdentity virIdentity; +typedef virIdentity *virIdentityPtr; + +typedef enum { + VIR_IDENTITY_ATTR_UNIX_USER_NAME, + VIR_IDENTITY_ATTR_UNIX_GROUP_NAME, + VIR_IDENTITY_ATTR_UNIX_PROCESS_ID, + VIR_IDENTITY_ATTR_SASL_USER_NAME, + VIR_IDENTITY_ATTR_X509_DISTINGUISHED_NAME, + VIR_IDENTITY_ATTR_SECURITY_CONTEXT, + + VIR_IDENTITY_ATTR_LAST, +} virIdentityAttrType; + + +virIdentityPtr virIdentityNew(void); +int virIdentityRef(virIdentityPtr ident); +int virIdentitySetAttr(virIdentityPtr ident, + unsigned int attr, + const char *value); + +int virIdentityGetAttr(virIdentityPtr ident, + unsigned int attr, + const char **value); + +int virIdentityIsEqual(virIdentityPtr identA, + virIdentityPtr identB); + +int virIdentityFree(virIdentityPtr ident); + /** * VIR_UUID_BUFLEN: * diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index e896d67..6db31d8 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -243,6 +243,7 @@ typedef enum { risky domain snapshot revert */ VIR_ERR_OPERATION_ABORTED = 78, /* operation on a domain was canceled/aborted by user */ + VIR_ERR_INVALID_IDENTITY = 79, /* Invalid identity pointer */ } virErrorNumber; /** diff --git a/src/datatypes.h b/src/datatypes.h index 91b1bfd..3cf3097 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -31,13 +31,23 @@ * VIR_CONNECT_MAGIC: * * magic value used to protect the API when pointers to connection structures - * are passed down by the uers. + * are passed down by the users. */ # define VIR_CONNECT_MAGIC 0x4F23DEAD # define VIR_IS_CONNECT(obj) ((obj) && (obj)->magic==VIR_CONNECT_MAGIC) /** + * VIR_IDENTITY_MAGIC: + * + * magic value used to protect the API when pointers to identity structures + * are passed down by the users. + */ +# define VIR_IDENTITY_MAGIC 0xB33FCAF3 +# define VIR_IS_IDENTITY(obj) ((obj) && (obj)->magic==VIR_IDENTITY_MAGIC) + + +/** * VIR_DOMAIN_MAGIC: * * magic value used to protect the API when pointers to domain structures @@ -190,6 +200,16 @@ struct _virConnect { int refs; /* reference count */ }; + +struct _virIdentity { + unsigned int magic; + virMutex lock; + int refs; + + char *attrs[VIR_IDENTITY_ATTR_LAST]; +}; + + /** * _virDomain: * diff --git a/src/libvirt.c b/src/libvirt.c index 7b8adf7..4ced8b9 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -1510,6 +1510,182 @@ virConnectRef(virConnectPtr conn) return 0; } + +virIdentityPtr virIdentityNew(void) +{ + virIdentityPtr ident; + + if (VIR_ALLOC(ident) < 0) { + virReportOOMError(); + return NULL; + } + + if (virMutexInit(&ident->lock) < 0) { + virReportSystemError(errno, "%s", + _("Unable to initialize mutex")); + VIR_FREE(ident); + return NULL; + } + ident->magic = VIR_IDENTITY_MAGIC; + ident->refs = 1; + + return ident; +} + +int virIdentityRef(virIdentityPtr ident) +{ + if ((!VIR_IS_IDENTITY(ident))) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + virMutexLock(&ident->lock); + VIR_DEBUG("ident=%p refs=%d", ident, ident->refs); + ident->refs++; + virMutexUnlock(&ident->lock); + return 0; +} + +int virIdentitySetAttr(virIdentityPtr ident, + unsigned int attr, + const char *value) +{ + VIR_DEBUG("ident=%p attribute=%u value=%s", ident, attr, NULLSTR(value)); + + if ((!VIR_IS_IDENTITY(ident))) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (attr >= VIR_IDENTITY_ATTR_LAST) { + virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (!value) { + virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + virMutexLock(&ident->lock); + + if (ident->attrs[attr]) { + virLibConnError(VIR_ERR_OPERATION_DENIED, "%s", + _("Identity attribute is already set")); + goto error; + } + + if (!(ident->attrs[attr] = strdup(value))) { + virReportOOMError(); + goto error; + } + + virMutexUnlock(&ident->lock); + return 0; + +error: + virDispatchError(NULL); + virMutexUnlock(&ident->lock); + return -1; +} + + +int virIdentityGetAttr(virIdentityPtr ident, + unsigned int attr, + const char **value) +{ + VIR_DEBUG("ident=%p attribute=%d value=%p", ident, attr, value); + + if ((!VIR_IS_IDENTITY(ident))) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (attr >= VIR_IDENTITY_ATTR_LAST) { + virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + virMutexLock(&ident->lock); + *value = ident->attrs[attr]; + virMutexUnlock(&ident->lock); + return 0; +} + + +int virIdentityIsEqual(virIdentityPtr identA, + virIdentityPtr identB) +{ + VIR_DEBUG("identA=%p identB=%p", identA, identB); + int ret = 0; + size_t i; + + if ((!VIR_IS_IDENTITY(identA))) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + if ((!VIR_IS_IDENTITY(identB))) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + virMutexLock(&identA->lock); + virMutexLock(&identB->lock); + + for (i = 0 ; i < VIR_IDENTITY_ATTR_LAST ; i++) { + if (identA->attrs[i] == NULL && + identB->attrs[i] != NULL) + goto cleanup; + if (identA->attrs[i] != NULL && + identB->attrs[i] == NULL) + goto cleanup; + if (STRNEQ(identA->attrs[i], + identB->attrs[i])) + goto cleanup; + } + + ret = 1; +cleanup: + virMutexUnlock(&identA->lock); + virMutexUnlock(&identB->lock); + return ret; +} + + +int virIdentityFree(virIdentityPtr ident) +{ + size_t i; + + if ((!VIR_IS_IDENTITY(ident))) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + virMutexLock(&ident->lock); + VIR_DEBUG("ident=%p refs=%d", ident, ident->refs); + ident->refs--; + if (ident->refs > 0) { + int ret = ident->refs; + virMutexUnlock(&ident->lock); + return ret; + } + for (i = 0 ; i < VIR_IDENTITY_ATTR_LAST ; i++) + VIR_FREE(ident->attrs[i]); + + virMutexUnlock(&ident->lock); + virMutexDestroy(&ident->lock); + VIR_FREE(ident); + return 0; +} + + + /* * Not for public use. This function is part of the internal * implementation of driver features in the remote case. diff --git a/src/util/virterror.c b/src/util/virterror.c index 380dc56..701aa2f 100644 --- a/src/util/virterror.c +++ b/src/util/virterror.c @@ -1219,6 +1219,12 @@ virErrorMsg(virErrorNumber error, const char *info) else errmsg = _("operation aborted: %s"); break; + case VIR_ERR_INVALID_IDENTITY: + if (info == NULL) + errmsg = _("invalid identity pointer in"); + else + errmsg = _("invalid identity pointer in %s"); + break; } return (errmsg); } -- 1.7.7.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list