mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 14:45:24 +00:00
Add ability to get a virIdentity from a virNetServerClientPtr
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>
This commit is contained in:
parent
8c5d28c1ad
commit
d5e83ad9b7
@ -852,6 +852,7 @@ virNetServerClientClose;
|
||||
virNetServerClientDelayedClose;
|
||||
virNetServerClientGetAuth;
|
||||
virNetServerClientGetFD;
|
||||
virNetServerClientGetIdentity;
|
||||
virNetServerClientGetPrivateData;
|
||||
virNetServerClientGetReadonly;
|
||||
virNetServerClientGetSecurityContext;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user