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:
Daniel P. Berrange 2012-01-23 15:05:01 +00:00
parent 8c5d28c1ad
commit d5e83ad9b7
3 changed files with 131 additions and 0 deletions

View File

@ -852,6 +852,7 @@ virNetServerClientClose;
virNetServerClientDelayedClose; virNetServerClientDelayedClose;
virNetServerClientGetAuth; virNetServerClientGetAuth;
virNetServerClientGetFD; virNetServerClientGetFD;
virNetServerClientGetIdentity;
virNetServerClientGetPrivateData; virNetServerClientGetPrivateData;
virNetServerClientGetReadonly; virNetServerClientGetReadonly;
virNetServerClientGetSecurityContext; virNetServerClientGetSecurityContext;

View File

@ -74,6 +74,9 @@ struct _virNetServerClient
int sockTimer; /* Timer to be fired upon cached data, int sockTimer; /* Timer to be fired upon cached data,
* so we jump out from poll() immediately */ * so we jump out from poll() immediately */
virIdentityPtr identity;
/* Count of messages in the 'tx' queue, /* Count of messages in the 'tx' queue,
* and the server worker pool queue * and the server worker pool queue
* ie RPC calls in progress. Does not count * 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, int virNetServerClientGetSecurityContext(virNetServerClientPtr client,
char **context) char **context)
{ {
@ -753,6 +878,8 @@ void virNetServerClientDispose(void *obj)
PROBE(RPC_SERVER_CLIENT_DISPOSE, PROBE(RPC_SERVER_CLIENT_DISPOSE,
"client=%p", client); "client=%p", client);
virObjectUnref(client->identity);
if (client->privateData && if (client->privateData &&
client->privateDataFreeFunc) client->privateDataFreeFunc)
client->privateDataFreeFunc(client->privateData); client->privateDataFreeFunc(client->privateData);

View File

@ -24,6 +24,7 @@
#ifndef __VIR_NET_SERVER_CLIENT_H__ #ifndef __VIR_NET_SERVER_CLIENT_H__
# define __VIR_NET_SERVER_CLIENT_H__ # define __VIR_NET_SERVER_CLIENT_H__
# include "viridentity.h"
# include "virnetsocket.h" # include "virnetsocket.h"
# include "virnetmessage.h" # include "virnetmessage.h"
# include "virobject.h" # include "virobject.h"
@ -103,6 +104,8 @@ int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client,
int virNetServerClientGetSecurityContext(virNetServerClientPtr client, int virNetServerClientGetSecurityContext(virNetServerClientPtr client,
char **context); char **context);
virIdentityPtr virNetServerClientGetIdentity(virNetServerClientPtr client);
void *virNetServerClientGetPrivateData(virNetServerClientPtr client); void *virNetServerClientGetPrivateData(virNetServerClientPtr client);
typedef void (*virNetServerClientCloseFunc)(virNetServerClientPtr client); typedef void (*virNetServerClientCloseFunc)(virNetServerClientPtr client);