From: "Daniel P. Berrange" <berrange(a)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(+)
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 7f589c8..d141465 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.10