[libvirt] [PATCH 09/12] Add ability to associate real/effective identity on virNetServerClientPtr

Daniel P. Berrange berrange at redhat.com
Wed May 2 11:44:16 UTC 2012


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

Add APIs which allow storage of a real & effective identity on
all server clients. Also add an API which allows creation of an
initial identity based on the results of client authentication
processes like TLS, x509, SASL, SO_PEERCRED
---
 src/rpc/virnetserverclient.c |  152 ++++++++++++++++++++++++++++++++++++++++++
 src/rpc/virnetserverclient.h |   11 +++
 2 files changed, 163 insertions(+)

diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
index 1e9d3db..9647ac3 100644
--- a/src/rpc/virnetserverclient.c
+++ b/src/rpc/virnetserverclient.c
@@ -75,6 +75,10 @@ struct _virNetServerClient
     int sockTimer; /* Timer to be fired upon cached data,
                     * so we jump out from poll() immediately */
 
+
+    virIdentityPtr realIdentity;
+    virIdentityPtr effectiveIdentity;
+
     /* Count of messages in the 'tx' queue,
      * and the server worker pool queue
      * ie RPC calls in progress. Does not count
@@ -487,6 +491,149 @@ int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client,
 }
 
 
+virIdentityPtr virNetServerClientGetIdentity(virNetServerClientPtr client)
+{
+    char *processid = NULL;
+    char *username = NULL;
+    char *groupname = NULL;
+#if HAVE_SASL
+    char *saslname = NULL;
+#endif
+    char *x509dname = NULL;
+    char *seccontext = NULL;
+    virIdentityPtr ret = NULL;
+    virNetSASLSessionPtr sasl;
+    virNetTLSSessionPtr tls;
+
+    if (virNetServerClientIsLocal(client)) {
+        gid_t gid;
+        uid_t uid;
+        pid_t pid;
+        if (virNetServerClientGetUNIXIdentity(client, &uid, &gid, &pid) < 0)
+            goto cleanup;
+
+        if (!(username = virGetUserName(uid)))
+            goto cleanup;
+        if (!(groupname = virGetGroupName(gid)))
+            goto cleanup;
+        if (virAsprintf(&processid, "%d", (int)pid) < 0)
+            goto cleanup;
+    }
+
+#if HAVE_SASL
+    if ((sasl = virNetServerClientGetSASLSession(client))) {
+        const char *identity = virNetSASLSessionGetIdentity(sasl);
+        if (identity &&
+            !(saslname = strdup(identity))) {
+            virReportOOMError();
+            goto cleanup;
+        }
+    }
+#endif
+
+    if ((tls = virNetServerClientGetTLSSession(client))) {
+        const char *identity = virNetTLSSessionGetX509DName(tls);
+        if (identity &&
+            !(x509dname = strdup(identity))) {
+            virReportOOMError();
+            goto cleanup;
+        }
+    }
+
+    if (virNetServerClientGetSecurityContext(client, &seccontext) < 0)
+        goto cleanup;
+
+    if (!(ret = virIdentityNew()))
+        goto cleanup;
+
+    if (username &&
+        virIdentitySetAttr(ret, VIR_IDENTITY_ATTR_UNIX_USER_NAME, username) < 0)
+        goto error;
+    if (groupname &&
+        virIdentitySetAttr(ret, VIR_IDENTITY_ATTR_UNIX_GROUP_NAME, groupname) < 0)
+        goto error;
+    if (processid &&
+        virIdentitySetAttr(ret, VIR_IDENTITY_ATTR_UNIX_PROCESS_ID, processid) < 0)
+        goto error;
+#if HAVE_SASL
+    if (saslname &&
+        virIdentitySetAttr(ret, VIR_IDENTITY_ATTR_SASL_USER_NAME, saslname) < 0)
+        goto error;
+#endif
+    if (x509dname &&
+        virIdentitySetAttr(ret, VIR_IDENTITY_ATTR_X509_DISTINGUISHED_NAME, x509dname) < 0)
+        goto error;
+    if (seccontext &&
+        virIdentitySetAttr(ret, VIR_IDENTITY_ATTR_SECURITY_CONTEXT, seccontext) < 0)
+        goto error;
+
+cleanup:
+    VIR_FREE(username);
+    VIR_FREE(groupname);
+    VIR_FREE(processid);
+    VIR_FREE(seccontext);
+#if HAVE_SASL
+    VIR_FREE(saslname);
+#endif
+    VIR_FREE(x509dname);
+    return ret;
+
+error:
+    virIdentityFree(ret);
+    ret = NULL;
+    goto cleanup;
+}
+
+
+virIdentityPtr virNetServerClientGetRealIdentity(virNetServerClientPtr client)
+{
+    virIdentityPtr ret;
+    virNetServerClientLock(client);
+    ret = client->realIdentity;
+    if (ret)
+        virIdentityRef(ret);
+    virNetServerClientUnlock(client);
+    return ret;
+}
+
+
+virIdentityPtr virNetServerClientGetEffectiveIdentity(virNetServerClientPtr client)
+{
+    virIdentityPtr ret;
+    virNetServerClientLock(client);
+    ret = client->effectiveIdentity;
+    if (ret)
+        virIdentityRef(ret);
+    virNetServerClientUnlock(client);
+    return ret;
+}
+
+
+void virNetServerClientSetRealIdentity(virNetServerClientPtr client,
+                                       virIdentityPtr ident)
+{
+    virNetServerClientLock(client);
+    if (client->realIdentity)
+        virIdentityFree(client->realIdentity);
+    if (ident)
+        virIdentityRef(ident);
+    client->realIdentity = ident;
+    virNetServerClientUnlock(client);
+}
+
+void virNetServerClientSetEffectiveIdentity(virNetServerClientPtr client,
+                                            virIdentityPtr ident)
+{
+    virNetServerClientLock(client);
+    if (client->effectiveIdentity)
+        virIdentityFree(client->effectiveIdentity);
+    if (ident)
+        virIdentityRef(ident);
+    client->effectiveIdentity = ident;
+    virNetServerClientUnlock(client);
+}
+
+
 int virNetServerClientGetSecurityContext(virNetServerClientPtr client,
                                          char **context)
 {
@@ -625,6 +772,11 @@ void virNetServerClientFree(virNetServerClientPtr client)
         return;
     }
 
+    if (client->realIdentity)
+        virIdentityFree(client->realIdentity);
+    if (client->effectiveIdentity)
+        virIdentityFree(client->effectiveIdentity);
+
     if (client->privateData &&
         client->privateDataFreeFunc)
         client->privateDataFreeFunc(client->privateData);
diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h
index a3b37a3..7435eee 100644
--- a/src/rpc/virnetserverclient.h
+++ b/src/rpc/virnetserverclient.h
@@ -77,6 +77,17 @@ int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client,
 int virNetServerClientGetSecurityContext(virNetServerClientPtr client,
                                          char **context);
 
+virIdentityPtr virNetServerClientGetIdentity(virNetServerClientPtr client);
+
+virIdentityPtr virNetServerClientGetRealIdentity(virNetServerClientPtr client);
+virIdentityPtr virNetServerClientGetEffectiveIdentity(virNetServerClientPtr client);
+
+void virNetServerClientSetRealIdentity(virNetServerClientPtr client,
+                                       virIdentityPtr ident);
+void virNetServerClientSetEffectiveIdentity(virNetServerClientPtr client,
+                                            virIdentityPtr iden);
+
+
 void virNetServerClientRef(virNetServerClientPtr client);
 
 typedef void (*virNetServerClientFreeFunc)(void *data);
-- 
1.7.10




More information about the libvir-list mailing list