[libvirt] [PATCH RFC 03/12] Define public API for managing identities

Daniel P. Berrange berrange at redhat.com
Mon Jan 23 17:34:11 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

---
 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




More information about the libvir-list mailing list