[libvirt] [PATCH 0/4] Misc patches to support RBAC work

The following patches aren't really needed on their own, rather they are part of the role based access control work I'm doing. In order to keep my patch queue small, I'm sending these out now, since there is no harm in merging them

From: "Daniel P. Berrange" <berrange@redhat.com> * daemon/remote.c, src/rpc/virnetserverclient.c, src/rpc/virnetserverclient.h, src/rpc/virnetsocket.c, src/rpc/virnetsocket.h: Add gid parameter --- daemon/remote.c | 9 ++++++--- src/rpc/virnetserverclient.c | 4 ++-- src/rpc/virnetserverclient.h | 2 +- src/rpc/virnetsocket.c | 3 +++ src/rpc/virnetsocket.h | 1 + 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index a28a754..80a2c1f 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -2030,6 +2030,7 @@ remoteDispatchAuthList(virNetServerPtr server ATTRIBUTE_UNUSED, int rv = -1; int auth = virNetServerClientGetAuth(client); uid_t callerUid; + gid_t callerGid; pid_t callerPid; /* If the client is root then we want to bypass the @@ -2037,7 +2038,7 @@ remoteDispatchAuthList(virNetServerPtr server ATTRIBUTE_UNUSED, * some piece of polkit isn't present/running */ if (auth == VIR_NET_SERVER_SERVICE_AUTH_POLKIT) { - if (virNetServerClientGetLocalIdentity(client, &callerUid, &callerPid) < 0) { + if (virNetServerClientGetLocalIdentity(client, &callerUid, &callerGid, &callerPid) < 0) { /* Don't do anything on error - it'll be validated at next * phase of auth anyway */ virResetLastError(); @@ -2463,6 +2464,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED, remote_auth_polkit_ret *ret) { pid_t callerPid = -1; + gid_t callerGid = -1; uid_t callerUid = -1; const char *action; int status = -1; @@ -2493,7 +2495,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED, goto authfail; } - if (virNetServerClientGetLocalIdentity(client, &callerUid, &callerPid) < 0) { + if (virNetServerClientGetLocalIdentity(client, &callerUid, &callerGid, &callerPid) < 0) { goto authfail; } @@ -2563,6 +2565,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server, remote_auth_polkit_ret *ret) { pid_t callerPid; + gid_t callerGid; uid_t callerUid; PolKitCaller *pkcaller = NULL; PolKitAction *pkaction = NULL; @@ -2590,7 +2593,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server, goto authfail; } - if (virNetServerClientGetLocalIdentity(client, &callerUid, &callerPid) < 0) { + if (virNetServerClientGetLocalIdentity(client, &callerUid, &callerGid, &callerPid) < 0) { VIR_ERROR(_("cannot get peer socket identity")); goto authfail; } diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c index cb07dd9..ed08e40 100644 --- a/src/rpc/virnetserverclient.c +++ b/src/rpc/virnetserverclient.c @@ -448,12 +448,12 @@ int virNetServerClientGetFD(virNetServerClientPtr client) } int virNetServerClientGetLocalIdentity(virNetServerClientPtr client, - uid_t *uid, pid_t *pid) + uid_t *uid, gid_t *gid, pid_t *pid) { int ret = -1; virNetServerClientLock(client); if (client->sock) - ret = virNetSocketGetLocalIdentity(client->sock, uid, pid); + ret = virNetSocketGetLocalIdentity(client->sock, uid, gid, pid); virNetServerClientUnlock(client); return ret; } diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h index a201dca..2dd01c5 100644 --- a/src/rpc/virnetserverclient.h +++ b/src/rpc/virnetserverclient.h @@ -71,7 +71,7 @@ int virNetServerClientSetIdentity(virNetServerClientPtr client, const char *virNetServerClientGetIdentity(virNetServerClientPtr client); int virNetServerClientGetLocalIdentity(virNetServerClientPtr client, - uid_t *uid, pid_t *pid); + uid_t *uid, gid_t *gid, pid_t *pid); void virNetServerClientRef(virNetServerClientPtr client); diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index af4fc5e..8178ac3 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -826,6 +826,7 @@ int virNetSocketGetPort(virNetSocketPtr sock) #ifdef SO_PEERCRED int virNetSocketGetLocalIdentity(virNetSocketPtr sock, uid_t *uid, + gid_t *gid, pid_t *pid) { struct ucred cr; @@ -841,6 +842,7 @@ int virNetSocketGetLocalIdentity(virNetSocketPtr sock, *pid = cr.pid; *uid = cr.uid; + *gid = cr.gid; virMutexUnlock(&sock->lock); return 0; @@ -848,6 +850,7 @@ int virNetSocketGetLocalIdentity(virNetSocketPtr sock, #else int virNetSocketGetLocalIdentity(virNetSocketPtr sock ATTRIBUTE_UNUSED, uid_t *uid ATTRIBUTE_UNUSED, + gid_t *gid ATTRIBUTE_UNUSED, pid_t *pid ATTRIBUTE_UNUSED) { /* XXX Many more OS support UNIX socket credentials we could port to. See dbus ....*/ diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h index ef9baa8..c2a040f 100644 --- a/src/rpc/virnetsocket.h +++ b/src/rpc/virnetsocket.h @@ -88,6 +88,7 @@ int virNetSocketGetPort(virNetSocketPtr sock); int virNetSocketGetLocalIdentity(virNetSocketPtr sock, uid_t *uid, + gid_t *gid, pid_t *pid); int virNetSocketSetBlocking(virNetSocketPtr sock, -- 1.7.7.5

From: "Daniel P. Berrange" <berrange@redhat.com> * daemon/remote.c: remoteSASLFinish called the method virNetSASLSessionGetIdentity twice, remove second call --- daemon/remote.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 80a2c1f..d917786 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -2198,7 +2198,6 @@ remoteSASLFinish(virNetServerClientPtr client) VIR_DEBUG("Authentication successful %d", virNetServerClientGetFD(client)); - identity = virNetSASLSessionGetIdentity(priv->sasl); PROBE(RPC_SERVER_CLIENT_AUTH_ALLOW, "client=%p auth=%d identity=%s", client, REMOTE_AUTH_SASL, identity); -- 1.7.7.5

From: "Daniel P. Berrange" <berrange@redhat.com> --- src/libvirt_private.syms | 1 + src/util/util.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++ src/util/util.h | 1 + 3 files changed, 57 insertions(+), 0 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0dfd4c1..8301c78 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1112,6 +1112,7 @@ virFindFileInPath; virFormatMacAddr; virGenerateMacAddr; virGetGroupID; +virGetGroupName; virGetHostname; virGetUserDirectory; virGetUserID; diff --git a/src/util/util.c b/src/util/util.c index 8663c4d..fdfceaa 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -2187,6 +2187,56 @@ static char *virGetUserEnt(uid_t uid, return ret; } +static char *virGetGroupEnt(gid_t gid) +{ + char *strbuf; + char *ret; + struct group grbuf; + struct group *gr = NULL; + long val = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t strbuflen = val; + int rc; + + /* sysconf is a hint; if it fails, fall back to a reasonable size */ + if (val < 0) + strbuflen = 1024; + + if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { + virReportOOMError(); + return NULL; + } + + /* + * From the manpage (terrifying but true): + * + * ERRORS + * 0 or ENOENT or ESRCH or EBADF or EPERM or ... + * The given name or gid was not found. + */ + while ((rc = getgrgid_r(gid, &grbuf, strbuf, strbuflen, &gr)) == ERANGE) { + if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) { + virReportOOMError(); + VIR_FREE(strbuf); + return NULL; + } + } + if (rc != 0 || gr == NULL) { + virReportSystemError(rc, + _("Failed to find group record for gid '%u'"), + (unsigned int) gid); + VIR_FREE(strbuf); + return NULL; + } + + ret = strdup(gr->gr_name); + + VIR_FREE(strbuf); + if (!ret) + virReportOOMError(); + + return ret; +} + char *virGetUserDirectory(uid_t uid) { return virGetUserEnt(uid, VIR_USER_ENT_DIRECTORY); @@ -2197,6 +2247,11 @@ char *virGetUserName(uid_t uid) return virGetUserEnt(uid, VIR_USER_ENT_NAME); } +char *virGetGroupName(gid_t gid) +{ + return virGetGroupEnt(gid); +} + int virGetUserID(const char *name, uid_t *uid) diff --git a/src/util/util.h b/src/util/util.h index 977ab6c..a380144 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -236,6 +236,7 @@ int virKillProcess(pid_t pid, int sig); char *virGetUserDirectory(uid_t uid); char *virGetUserName(uid_t uid); +char *virGetGroupName(gid_t gid); int virGetUserID(const char *name, uid_t *uid) ATTRIBUTE_RETURN_CHECK; int virGetGroupID(const char *name, -- 1.7.7.5

From: "Daniel P. Berrange" <berrange@redhat.com> To avoid a namespace clash with forthcoming identity APIs, rename the virNet*GetLocalIdentity() APIs to have the form virNet*GetUNIXIdentity() * daemon/remote.c, src/libvirt_private.syms: Update for renamed APIs * src/rpc/virnetserverclient.c, src/rpc/virnetserverclient.h, src/rpc/virnetsocket.c, src/rpc/virnetsocket.h: s/LocalIdentity/UNIXIdentity/ --- daemon/remote.c | 6 +++--- src/libvirt_private.syms | 2 +- src/rpc/virnetserverclient.c | 6 +++--- src/rpc/virnetserverclient.h | 4 ++-- src/rpc/virnetsocket.c | 16 ++++++++-------- src/rpc/virnetsocket.h | 8 ++++---- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index d917786..3b8ccd9 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -2038,7 +2038,7 @@ remoteDispatchAuthList(virNetServerPtr server ATTRIBUTE_UNUSED, * some piece of polkit isn't present/running */ if (auth == VIR_NET_SERVER_SERVICE_AUTH_POLKIT) { - if (virNetServerClientGetLocalIdentity(client, &callerUid, &callerGid, &callerPid) < 0) { + if (virNetServerClientGetUNIXIdentity(client, &callerUid, &callerGid, &callerPid) < 0) { /* Don't do anything on error - it'll be validated at next * phase of auth anyway */ virResetLastError(); @@ -2494,7 +2494,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED, goto authfail; } - if (virNetServerClientGetLocalIdentity(client, &callerUid, &callerGid, &callerPid) < 0) { + if (virNetServerClientGetUNIXIdentity(client, &callerUid, &callerGid, &callerPid) < 0) { goto authfail; } @@ -2592,7 +2592,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server, goto authfail; } - if (virNetServerClientGetLocalIdentity(client, &callerUid, &callerGid, &callerPid) < 0) { + if (virNetServerClientGetUNIXIdentity(client, &callerUid, &callerGid, &callerPid) < 0) { VIR_ERROR(_("cannot get peer socket identity")); goto authfail; } diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8301c78..cf17ed1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1291,7 +1291,7 @@ virNetServerClientDelayedClose; virNetServerClientFree; virNetServerClientGetAuth; virNetServerClientGetFD; -virNetServerClientGetLocalIdentity; +virNetServerClientGetUNIXIdentity; virNetServerClientGetPrivateData; virNetServerClientGetReadonly; virNetServerClientGetTLSKeySize; diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c index ed08e40..67600fd 100644 --- a/src/rpc/virnetserverclient.c +++ b/src/rpc/virnetserverclient.c @@ -447,13 +447,13 @@ int virNetServerClientGetFD(virNetServerClientPtr client) return fd; } -int virNetServerClientGetLocalIdentity(virNetServerClientPtr client, - uid_t *uid, gid_t *gid, pid_t *pid) +int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client, + uid_t *uid, gid_t *gid, pid_t *pid) { int ret = -1; virNetServerClientLock(client); if (client->sock) - ret = virNetSocketGetLocalIdentity(client->sock, uid, gid, pid); + ret = virNetSocketGetUNIXIdentity(client->sock, uid, gid, pid); virNetServerClientUnlock(client); return ret; } diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h index 2dd01c5..154a160 100644 --- a/src/rpc/virnetserverclient.h +++ b/src/rpc/virnetserverclient.h @@ -70,8 +70,8 @@ int virNetServerClientSetIdentity(virNetServerClientPtr client, const char *identity); const char *virNetServerClientGetIdentity(virNetServerClientPtr client); -int virNetServerClientGetLocalIdentity(virNetServerClientPtr client, - uid_t *uid, gid_t *gid, pid_t *pid); +int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client, + uid_t *uid, gid_t *gid, pid_t *pid); void virNetServerClientRef(virNetServerClientPtr client); diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index 8178ac3..67d33b7 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -824,10 +824,10 @@ int virNetSocketGetPort(virNetSocketPtr sock) #ifdef SO_PEERCRED -int virNetSocketGetLocalIdentity(virNetSocketPtr sock, - uid_t *uid, - gid_t *gid, - pid_t *pid) +int virNetSocketGetUNIXIdentity(virNetSocketPtr sock, + uid_t *uid, + gid_t *gid, + pid_t *pid) { struct ucred cr; socklen_t cr_len = sizeof (cr); @@ -848,10 +848,10 @@ int virNetSocketGetLocalIdentity(virNetSocketPtr sock, return 0; } #else -int virNetSocketGetLocalIdentity(virNetSocketPtr sock ATTRIBUTE_UNUSED, - uid_t *uid ATTRIBUTE_UNUSED, - gid_t *gid ATTRIBUTE_UNUSED, - pid_t *pid ATTRIBUTE_UNUSED) +int virNetSocketGetUNIXIdentity(virNetSocketPtr sock ATTRIBUTE_UNUSED, + uid_t *uid ATTRIBUTE_UNUSED, + gid_t *gid ATTRIBUTE_UNUSED, + pid_t *pid ATTRIBUTE_UNUSED) { /* XXX Many more OS support UNIX socket credentials we could port to. See dbus ....*/ virReportSystemError(ENOSYS, "%s", diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h index c2a040f..5ba7c8f 100644 --- a/src/rpc/virnetsocket.h +++ b/src/rpc/virnetsocket.h @@ -86,10 +86,10 @@ bool virNetSocketHasPassFD(virNetSocketPtr sock); int virNetSocketGetPort(virNetSocketPtr sock); -int virNetSocketGetLocalIdentity(virNetSocketPtr sock, - uid_t *uid, - gid_t *gid, - pid_t *pid); +int virNetSocketGetUNIXIdentity(virNetSocketPtr sock, + uid_t *uid, + gid_t *gid, + pid_t *pid); int virNetSocketSetBlocking(virNetSocketPtr sock, bool blocking); -- 1.7.7.5

On 01/19/2012 06:51 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
To avoid a namespace clash with forthcoming identity APIs, rename the virNet*GetLocalIdentity() APIs to have the form virNet*GetUNIXIdentity()
* daemon/remote.c, src/libvirt_private.syms: Update for renamed APIs * src/rpc/virnetserverclient.c, src/rpc/virnetserverclient.h, src/rpc/virnetsocket.c, src/rpc/virnetsocket.h: s/LocalIdentity/UNIXIdentity/
+++ b/src/libvirt_private.syms @@ -1291,7 +1291,7 @@ virNetServerClientDelayedClose; virNetServerClientFree; virNetServerClientGetAuth; virNetServerClientGetFD; -virNetServerClientGetLocalIdentity; +virNetServerClientGetUNIXIdentity; virNetServerClientGetPrivateData;
This rename implies a different sorting order. Other than that nit, ACK to the series. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Daniel P. Berrange
-
Eric Blake