]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add ability to get a virIdentity from a virNetServerClientPtr
authorDaniel P. Berrange <berrange@redhat.com>
Mon, 23 Jan 2012 15:05:01 +0000 (15:05 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 19 Mar 2013 13:52:02 +0000 (13:52 +0000)
Add APIs which allow creation of a virIdentity from the info
associated with a virNetServerClientPtr instance. This is done
based on the results of client authentication processes like
TLS, x509, SASL, SO_PEERCRED

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/libvirt_private.syms
src/rpc/virnetserverclient.c
src/rpc/virnetserverclient.h

index 29768f6b7fe69f71eef60bfbc45a33c9a19708da..d0ab71ba2cf71ca12aaccc3e6d9f4a465449729a 100644 (file)
@@ -852,6 +852,7 @@ virNetServerClientClose;
 virNetServerClientDelayedClose;
 virNetServerClientGetAuth;
 virNetServerClientGetFD;
+virNetServerClientGetIdentity;
 virNetServerClientGetPrivateData;
 virNetServerClientGetReadonly;
 virNetServerClientGetSecurityContext;
index 3edcd3c3c1a33292f06b48c9b4d291102dbd3752..d407f5e398f6ec2938d2107ac63e949fba782921 100644 (file)
@@ -74,6 +74,9 @@ struct _virNetServerClient
     int sockTimer; /* Timer to be fired upon cached data,
                     * so we jump out from poll() immediately */
 
+
+    virIdentityPtr identity;
+
     /* Count of messages in the 'tx' queue,
      * and the server worker pool queue
      * ie RPC calls in progress. Does not count
@@ -642,6 +645,128 @@ int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client,
 }
 
 
+static virIdentityPtr
+virNetServerClientCreateIdentity(virNetServerClientPtr client)
+{
+    char *processid = NULL;
+    char *username = NULL;
+    char *groupname = NULL;
+#if WITH_SASL
+    char *saslname = NULL;
+#endif
+    char *x509dname = NULL;
+    char *seccontext = NULL;
+    virIdentityPtr ret = NULL;
+
+    if (client->sock && virNetSocketIsLocal(client->sock)) {
+        gid_t gid;
+        uid_t uid;
+        pid_t pid;
+        if (virNetSocketGetUNIXIdentity(client->sock, &uid, &gid, &pid) < 0)
+            goto cleanup;
+
+        if (!(username = virGetUserName(uid)))
+            goto cleanup;
+        if (!(groupname = virGetGroupName(gid)))
+            goto cleanup;
+        if (virAsprintf(&processid, "%lld",
+                        (long long)pid) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+    }
+
+#if WITH_SASL
+    if (client->sasl) {
+        const char *identity = virNetSASLSessionGetIdentity(client->sasl);
+        if (identity &&
+            !(saslname = strdup(identity))) {
+            virReportOOMError();
+            goto cleanup;
+        }
+    }
+#endif
+
+    if (client->tls) {
+        const char *identity = virNetTLSSessionGetX509DName(client->tls);
+        if (identity &&
+            !(x509dname = strdup(identity))) {
+            virReportOOMError();
+            goto cleanup;
+        }
+    }
+
+    if (client->sock &&
+        virNetSocketGetSecurityContext(client->sock, &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:
+    virObjectUnref(ret);
+    ret = NULL;
+    goto cleanup;
+}
+
+
+virIdentityPtr virNetServerClientGetIdentity(virNetServerClientPtr client)
+{
+    virIdentityPtr ret = NULL;
+    virObjectLock(client);
+    if (!client->identity)
+        client->identity = virNetServerClientCreateIdentity(client);
+    if (client->identity)
+        ret = virObjectRef(client->identity);
+    virObjectUnlock(client);
+    return ret;
+}
+
+
 int virNetServerClientGetSecurityContext(virNetServerClientPtr client,
                                          char **context)
 {
@@ -753,6 +878,8 @@ void virNetServerClientDispose(void *obj)
     PROBE(RPC_SERVER_CLIENT_DISPOSE,
           "client=%p", client);
 
+    virObjectUnref(client->identity);
+
     if (client->privateData &&
         client->privateDataFreeFunc)
         client->privateDataFreeFunc(client->privateData);
index f8643f5873476abea229e0ed6c1f0e19328acc6e..b3b8df0bf963b7febd277649b35820c9417b4e74 100644 (file)
@@ -24,6 +24,7 @@
 #ifndef __VIR_NET_SERVER_CLIENT_H__
 # define __VIR_NET_SERVER_CLIENT_H__
 
+# include "viridentity.h"
 # include "virnetsocket.h"
 # include "virnetmessage.h"
 # include "virobject.h"
@@ -103,6 +104,8 @@ int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client,
 int virNetServerClientGetSecurityContext(virNetServerClientPtr client,
                                          char **context);
 
+virIdentityPtr virNetServerClientGetIdentity(virNetServerClientPtr client);
+
 void *virNetServerClientGetPrivateData(virNetServerClientPtr client);
 
 typedef void (*virNetServerClientCloseFunc)(virNetServerClientPtr client);