[libvirt] [PATCH RFC 08/12] Set the identity for the access manager during API call dispatch

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


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

When dispatching an RPC API call, setup the access manager to hold
the real & effective identities of the current server client whose
RPC is being dispatched. The setting is thread-local, so only
affects the API call in this thread
---
 src/rpc/virnetserverclient.c  |   41 +++++++++++++++++++++++++++++++++++++++++
 src/rpc/virnetserverclient.h  |    3 +++
 src/rpc/virnetserverprogram.c |    9 +++++++++
 3 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
index 9647ac3..043938e 100644
--- a/src/rpc/virnetserverclient.c
+++ b/src/rpc/virnetserverclient.c
@@ -34,6 +34,7 @@
 #include "memory.h"
 #include "threads.h"
 #include "virkeepalive.h"
+#include "access/viraccessmanager.h"
 
 #define VIR_FROM_THIS VIR_FROM_RPC
 #define virNetError(code, ...)                                    \
@@ -634,6 +635,46 @@ void virNetServerClientSetEffectiveIdentity(virNetServerClientPtr client,
 }
 
 
+int virNetServerClientActivateIdentity(virNetServerClientPtr client)
+{
+    virIdentityPtr real;
+    virIdentityPtr effective;
+    virIdentityPtr sys = NULL;
+    int ret = -1;
+
+    real = virNetServerClientGetRealIdentity(client);
+    effective = virNetServerClientGetEffectiveIdentity(client);
+    if ((!real || !effective) &&
+        !(sys = virAccessManagerGetSystemIdentity()))
+        goto cleanup;
+
+    if (virAccessManagerSetRealIdentity(real ? real : sys) < 0)
+        goto cleanup;
+    if (virAccessManagerSetEffectiveIdentity(effective ? effective : sys) < 0)
+        goto cleanup;
+
+    ret = 0;
+cleanup:
+    if (real)
+        virIdentityFree(real);
+    if (effective)
+        virIdentityFree(effective);
+    if (sys)
+        virIdentityFree(sys);
+    return ret;
+}
+
+
+int virNetServerClientDeactivateIdentity(virNetServerClientPtr client ATTRIBUTE_UNUSED)
+{
+    if (virAccessManagerSetRealIdentity(NULL) < 0)
+        return -1;
+    if (virAccessManagerSetEffectiveIdentity(NULL) < 0)
+        return -1;
+    return 0;
+}
+
+
 int virNetServerClientGetSecurityContext(virNetServerClientPtr client,
                                          char **context)
 {
diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h
index 7435eee..f3c95cc 100644
--- a/src/rpc/virnetserverclient.h
+++ b/src/rpc/virnetserverclient.h
@@ -87,6 +87,9 @@ void virNetServerClientSetRealIdentity(virNetServerClientPtr client,
 void virNetServerClientSetEffectiveIdentity(virNetServerClientPtr client,
                                             virIdentityPtr iden);
 
+int virNetServerClientActivateIdentity(virNetServerClientPtr client);
+int virNetServerClientDeactivateIdentity(virNetServerClientPtr client);
+
 
 void virNetServerClientRef(virNetServerClientPtr client);
 
diff --git a/src/rpc/virnetserverprogram.c b/src/rpc/virnetserverprogram.c
index d2ede6b..d4d56ff 100644
--- a/src/rpc/virnetserverprogram.c
+++ b/src/rpc/virnetserverprogram.c
@@ -403,6 +403,9 @@ virNetServerProgramDispatchCall(virNetServerProgramPtr prog,
     if (virNetMessageDecodePayload(msg, dispatcher->arg_filter, arg) < 0)
         goto error;
 
+    if (virNetServerClientActivateIdentity(client) < 0)
+        goto error;
+
     /*
      * When the RPC handler is called:
      *
@@ -415,6 +418,12 @@ virNetServerProgramDispatchCall(virNetServerProgramPtr prog,
      */
     rv = (dispatcher->func)(server, client, msg, &rerr, arg, ret);
 
+    if (virNetServerClientDeactivateIdentity(client) < 0) {
+        virErrorPtr err = virGetLastError();
+        VIR_WARN("Failed to deactive identity %s", err ? err->message : "null");
+        virResetLastError();
+    }
+
     /*
      * Clear out the FDs we got from the client, we don't
      * want to send them back !
-- 
1.7.7.5




More information about the libvir-list mailing list