From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list