When using the fine grained access control mechanism for APIs, when a
client connects to libvirtd, the latter will fetch the uid, gid, selinux
info of the remote client on the UNIX domain socket. This is then used
as the identity when checking ACLs.
With the new split daemons things are a bit more complicated. The user
can connect to virtproxyd, which in turn connects to virtqemud. When
virtqemud requests the identity over the UNIX domain socket, it will
get the identity that virtproxyd is running as, not the identity of
the real end user/application.
virproxyd knows what the real identity is, and needs to be able to
forward this information to virtqemud. The virConnectSetIdentity API
provides a mechanism for doing this. Obviously virtqemud should not
accept such identity overrides from any client, it must only honour it
from a trusted client, aka one running as the same uid/gid as itself.
The typed parameters exposed in the API are the same as those currently
supported by the internal virIdentity class, with a few small name
changes.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
include/libvirt/libvirt-host.h | 74 ++++++++++++++++++++++++++++++++++
src/driver-hypervisor.h | 7 ++++
src/libvirt-host.c | 51 +++++++++++++++++++++++
src/libvirt_public.syms | 4 ++
4 files changed, 136 insertions(+)
diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index 7debb5f829..be65b4686b 100644
--- a/include/libvirt/libvirt-host.h
+++ b/include/libvirt/libvirt-host.h
@@ -579,6 +579,80 @@ virConnectPtr virConnectOpenAuth (const char *name,
unsigned int flags);
int virConnectRef (virConnectPtr conn);
int virConnectClose (virConnectPtr conn);
+
+/**
+ * VIR_CONNECT_IDENTITY_USER_NAME:
+ *
+ * The operating system user name as VIR_TYPED_PARAM_STRING.
+ */
+# define VIR_CONNECT_IDENTITY_USER_NAME "user-name"
+
+/**
+ * VIR_CONNECT_IDENTITY_UNIX_USER_ID:
+ *
+ * The UNIX user ID as VIR_TYPED_PARAM_ULLONG.
+ */
+# define VIR_CONNECT_IDENTITY_UNIX_USER_ID "unix-user-id"
+
+/**
+ * VIR_CONNECT_IDENTITY_GROUP_NAME:
+ *
+ * The operating system group name as VIR_TYPED_PARAM_STRING.
+ */
+# define VIR_CONNECT_IDENTITY_GROUP_NAME "group-name"
+
+/**
+ * VIR_CONNECT_IDENTITY_UNIX_GROUP_ID:
+ *
+ * The UNIX group ID as VIR_TYPED_PARAM_ULLONG.
+ */
+# define VIR_CONNECT_IDENTITY_UNIX_GROUP_ID "unix-group-id"
+
+/**
+ * VIR_CONNECT_IDENTITY_PROCESS_ID:
+ *
+ * The operating system process ID as VIR_TYPED_PARAM_LLONG.
+ */
+# define VIR_CONNECT_IDENTITY_PROCESS_ID "process-id"
+
+/**
+ * VIR_CONNECT_IDENTITY_PROCESS_TIME:
+ *
+ * The operating system process start time as VIR_TYPED_PARAM_ULLONG.
+ *
+ * The units the time is measured in vary according to the
+ * host operating system. On Linux this is usually clock
+ * ticks (as reported in /proc/$PID/stat field 22).
+ */
+# define VIR_CONNECT_IDENTITY_PROCESS_TIME "process-time"
+
+/**
+ * VIR_CONNECT_IDENTITY_SASL_USER_NAME:
+ *
+ * The SASL authenticated username as VIR_TYPED_PARAM_STRING
+ */
+# define VIR_CONNECT_IDENTITY_SASL_USER_NAME "sasl-user-name"
+
+/**
+ * VIR_CONNECT_IDENTITY_X509_DISTINGUISHED_NAME:
+ *
+ * The TLS x509 certificate distinguished named as VIR_TYPED_PARAM_STRING
+ */
+# define VIR_CONNECT_IDENTITY_X509_DISTINGUISHED_NAME
"x509-distinguished-name"
+
+/**
+ * VIR_CONNECT_IDENTITY_SELINUX_CONTEXT:
+ *
+ * The application's SELinux context as VIR_TYPED_PARAM_STRING.
+ */
+# define VIR_CONNECT_IDENTITY_SELINUX_CONTEXT "selinux-context"
+
+
+int virConnectSetIdentity (virConnectPtr conn,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags);
+
const char * virConnectGetType (virConnectPtr conn);
int virConnectGetVersion (virConnectPtr conn,
unsigned long *hvVer);
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 58eb731e85..015b2cd01c 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -36,6 +36,12 @@ typedef virDrvOpenStatus
typedef int
(*virDrvConnectClose)(virConnectPtr conn);
+typedef int
+(*virDrvConnectSetIdentity)(virConnectPtr conn,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags);
+
typedef int
(*virDrvConnectSupportsFeature)(virConnectPtr conn,
int feature);
@@ -1385,6 +1391,7 @@ struct _virHypervisorDriver {
virDrvConnectURIProbe connectURIProbe;
virDrvConnectOpen connectOpen;
virDrvConnectClose connectClose;
+ virDrvConnectSetIdentity connectSetIdentity;
virDrvConnectSupportsFeature connectSupportsFeature;
virDrvConnectGetType connectGetType;
virDrvConnectGetVersion connectGetVersion;
diff --git a/src/libvirt-host.c b/src/libvirt-host.c
index e5c4e5f72a..d7b1b82277 100644
--- a/src/libvirt-host.c
+++ b/src/libvirt-host.c
@@ -61,6 +61,57 @@ virConnectRef(virConnectPtr conn)
}
+/**
+ * virConnectSetIdentity:
+ * @conn: pointer to the hypervisor connection
+ * @params: parameters containing the identity attributes
+ * @nparams: size of @params array
+ * @flags: currently unused, pass 0
+ *
+ * Override the default identity information associated with
+ * the connection. When connecting to a stateful driver over
+ * a UNIX socket, the daemon will interrogate the remote end
+ * of the UNIX socket to acquire the application's identity.
+ * This identity is used for the fine grained access control
+ * checks on API calls.
+ *
+ * There may be times when application is operating on behalf
+ * of a variety of users, and thus the identity that the
+ * application runs as is not appropriate for access control
+ * checks. In this case, if the application is considered
+ * trustworthy, it can supply alternative identity information.
+ *
+ * The driver may reject the request to change the identity
+ * on a connection if the application is not trustworthy.
+ *
+ * Returns: 0 if the identity change was accepted, -1 on error
+ */
+int
+virConnectSetIdentity(virConnectPtr conn,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p params=%p nparams=%d flags=0x%x", conn, params, nparams,
flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ if (conn->driver->connectSetIdentity) {
+ int ret = conn->driver->connectSetIdentity(conn, params, nparams, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
/*
* Not for public use. This function is part of the internal
* implementation of driver features in the remote case.
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 252f061ba3..40655fbbf5 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -857,4 +857,8 @@ LIBVIRT_5.7.0 {
virDomainGetGuestInfo;
} LIBVIRT_5.6.0;
+LIBVIRT_5.8.0 {
+ virConnectSetIdentity;
+} LIBVIRT_5.7.0;
+
# .... define new API here using predicted next version number ....
--
2.21.0