[PATCH] Fix build when using polkit0

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Here's a hacked attempt at fixing the build on older distros using
polkit0.  It works and user is authorized or denied depending on
settings in PolicyKit.conf.

I'm not too happy with it but haven't yet digested all the changes in
rpc and daemon code.  In the meantime, hopefully someone can suggest
improvements.

Regards,
Jim


>From 3341912b3d34b363c6ecd922dd2489247a568f2e Mon Sep 17 00:00:00 2001
From: Jim Fehlig <jfehlig@xxxxxxxxxx>
Date: Thu, 7 Jul 2011 15:12:26 -0600
Subject: [PATCH] Fix build when using polkit0

---
 daemon/libvirtd.c      |   24 ++++--------------------
 daemon/libvirtd.h      |   26 --------------------------
 daemon/remote.c        |   21 ++++++++++-----------
 src/Makefile.am        |    4 +++-
 src/rpc/virnetserver.c |   40 ++++++++++++++++++++++++++++++++++++++++
 src/rpc/virnetserver.h |    8 ++++++++
 6 files changed, 65 insertions(+), 58 deletions(-)

diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 06d2077..ddfcb79 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -576,26 +576,6 @@ static int daemonSetupNetworking(virNetServerPtr srv,
     }
 #endif
 
-#if HAVE_POLKIT0
-    if (auth_unix_rw == REMOTE_AUTH_POLKIT ||
-        auth_unix_ro == REMOTE_AUTH_POLKIT) {
-        DBusError derr;
-
-        dbus_connection_set_change_sigpipe(FALSE);
-        dbus_threads_init_default();
-
-        dbus_error_init(&derr);
-        server->sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &derr);
-        if (!(server->sysbus)) {
-            VIR_ERROR(_("Failed to connect to system bus for PolicyKit auth: %s"),
-                      derr.message);
-            dbus_error_free(&derr);
-            goto error;
-        }
-        dbus_connection_set_exit_on_disconnect(server->sysbus, FALSE);
-    }
-#endif
-
     return 0;
 
 error:
@@ -1278,6 +1258,7 @@ int main(int argc, char **argv) {
     int ipsock = 0;
     struct daemonConfig *config;
     bool privileged = geteuid() == 0 ? true : false;
+    bool use_polkit;
 
     struct option opts[] = {
         { "verbose", no_argument, &verbose, 1},
@@ -1436,10 +1417,13 @@ int main(int argc, char **argv) {
         umask(old_umask);
     }
 
+    use_polkit = config->auth_unix_rw == REMOTE_AUTH_POLKIT ||
+            config->auth_unix_ro == REMOTE_AUTH_POLKIT;
     if (!(srv = virNetServerNew(config->min_workers,
                                 config->max_workers,
                                 config->max_clients,
                                 config->mdns_adv ? config->mdns_name : NULL,
+                                use_polkit,
                                 remoteClientInitHook))) {
         ret = VIR_DAEMON_ERR_INIT;
         goto cleanup;
diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h
index 8e1843c..18a10ef 100644
--- a/daemon/libvirtd.h
+++ b/daemon/libvirtd.h
@@ -91,30 +91,4 @@ extern virNetSASLContextPtr saslCtxt;
 extern virNetServerProgramPtr remoteProgram;
 extern virNetServerProgramPtr qemuProgram;
 
-/* Main server state */
-struct qemud_server {
-    int privileged;
-
-    int sigread;
-    int sigwrite;
-    char *logDir;
-    pthread_t eventThread;
-    unsigned int hasEventThread :1;
-    unsigned int quitEventThread :1;
-# ifdef HAVE_AVAHI
-    struct libvirtd_mdns *mdns;
-# endif
-# if HAVE_SASL
-    char **saslUsernameWhitelist;
-# endif
-# if HAVE_POLKIT0
-    DBusConnection *sysbus;
-# endif
-};
-
-
-# if HAVE_POLKIT
-int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid);
-# endif
-
 #endif
diff --git a/daemon/remote.c b/daemon/remote.c
index 2889908..0fc26c6 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -43,6 +43,7 @@
 #include "command.h"
 #include "intprops.h"
 #include "virnetserverservice.h"
+#include "virnetserver.h"
 
 #include "remote_protocol.h"
 #include "qemu_protocol.h"
@@ -2115,7 +2116,7 @@ authdeny:
 }
 #elif HAVE_POLKIT0
 static int
-remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
+remoteDispatchAuthPolkit(virNetServerPtr server,
                          virNetServerClientPtr client,
                          virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
                          virNetMessageErrorPtr rerr,
@@ -2137,21 +2138,19 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
 
     memset(ident, 0, sizeof ident);
 
-    virMutexLock(&server->lock);
-    virMutexLock(&client->lock);
-    virMutexUnlock(&server->lock);
+    virMutexLock(&priv->lock);
 
-    action = client->readonly ?
+    action = virNetServerClientGetReadonly(client) ?
         "org.libvirt.unix.monitor" :
         "org.libvirt.unix.manage";
 
     VIR_DEBUG("Start PolicyKit auth %d", virNetServerClientGetFD(client));
-    if (client->auth != REMOTE_AUTH_POLKIT) {
+    if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_POLKIT) {
         VIR_ERROR(_("client tried invalid PolicyKit init request"));
         goto authfail;
     }
 
-    if (qemudGetSocketIdentity(virNetServerClientGetFD(client), &callerUid, &callerPid) < 0) {
+    if (virNetServerClientGetLocalIdentity(client, &callerUid, &callerPid) < 0) {
         VIR_ERROR(_("cannot get peer socket identity"));
         goto authfail;
     }
@@ -2164,7 +2163,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
 
     VIR_INFO("Checking PID %d running as %d", callerPid, callerUid);
     dbus_error_init(&err);
-    if (!(pkcaller = polkit_caller_new_from_pid(server->sysbus,
+    if (!(pkcaller = polkit_caller_new_from_pid(virNetServerGetDBusConn(server),
                                                 callerPid, &err))) {
         VIR_ERROR(_("Failed to lookup policy kit caller: %s"), err.message);
         dbus_error_free(&err);
@@ -2226,9 +2225,9 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
              action, callerPid, callerUid,
              polkit_result_to_string_representation(pkresult));
     ret->complete = 1;
-    client->auth = REMOTE_AUTH_NONE;
+    virNetServerClientSetIdentity(client, ident);
 
-    virMutexUnlock(&client->lock);
+    virMutexUnlock(&priv->lock);
     return 0;
 
 error:
@@ -2236,7 +2235,7 @@ error:
     virNetError(VIR_ERR_AUTH_FAILED, "%s",
                 _("authentication failed"));
     virNetMessageSaveError(rerr);
-    virMutexUnlock(&client->lock);
+    virMutexUnlock(&priv->lock);
     return -1;
 
 authfail:
diff --git a/src/Makefile.am b/src/Makefile.am
index cd8a7e9..a3ee8ba 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1268,10 +1268,12 @@ EXTRA_DIST += \
 endif
 libvirt_net_rpc_server_la_CFLAGS = \
 			$(AVAHI_CFLAGS) \
-			$(AM_CFLAGS)
+			$(AM_CFLAGS) \
+			$(POLKIT_CFLAGS)
 libvirt_net_rpc_server_la_LDFLAGS = \
 			$(AM_LDFLAGS) \
 			$(AVAHI_LIBS) \
+			$(POLKIT_LIBS) \
 			$(CYGWIN_EXTRA_LDFLAGS) \
 			$(MINGW_EXTRA_LDFLAGS)
 libvirt_net_rpc_server_la_LIBADD = \
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 5e1719b..6e9eb2c 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -39,6 +39,9 @@
 #if HAVE_AVAHI
 # include "virnetservermdns.h"
 #endif
+#if HAVE_POLKIT0
+# include <dbus/dbus.h>
+#endif
 
 #define VIR_FROM_THIS VIR_FROM_RPC
 #define virNetError(code, ...)                                    \
@@ -84,6 +87,10 @@ struct _virNetServer {
     virNetServerMDNSGroupPtr mdnsGroup;
 #endif
 
+#if HAVE_POLKIT0
+    DBusConnection *sysbus;
+#endif
+
     size_t nservices;
     virNetServerServicePtr *services;
 
@@ -270,6 +277,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
                                 size_t max_workers,
                                 size_t max_clients,
                                 const char *mdnsGroupName,
+                                bool usePolkit,
                                 virNetServerClientInitHook clientInitHook)
 {
     virNetServerPtr srv;
@@ -306,6 +314,25 @@ virNetServerPtr virNetServerNew(size_t min_workers,
     }
 #endif
 
+#if HAVE_POLKIT0
+    if (usePolkit) {
+        DBusError derr;
+
+        dbus_connection_set_change_sigpipe(FALSE);
+        dbus_threads_init_default();
+
+        dbus_error_init(&derr);
+        srv->sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &derr);
+        if (!(srv->sysbus)) {
+            VIR_ERROR(_("Failed to connect to system bus for PolicyKit auth: %s"),
+                      derr.message);
+            dbus_error_free(&derr);
+            goto error;
+        }
+        dbus_connection_set_exit_on_disconnect(srv->sysbus, FALSE);
+    }
+#endif
+
     if (virMutexInit(&srv->lock) < 0) {
         virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
                     _("cannot initialize mutex"));
@@ -363,6 +390,14 @@ bool virNetServerIsPrivileged(virNetServerPtr srv)
 }
 
 
+#if HAVE_POLKIT0
+DBusConnection* virNetServerGetDBusConn(virNetServerPtr srv)
+{
+    return srv->sysbus;
+}
+#endif
+
+
 void virNetServerAutoShutdown(virNetServerPtr srv,
                               unsigned int timeout,
                               virNetServerAutoShutdownFunc func,
@@ -747,6 +782,11 @@ void virNetServerFree(virNetServerPtr srv)
 
     VIR_FREE(srv->mdnsGroupName);
 
+#if HAVE_POLKIT0
+        if (srv->sysbus)
+            dbus_connection_unref(srv->sysbus);
+#endif
+
     virNetServerUnlock(srv);
     virMutexDestroy(&srv->lock);
     VIR_FREE(srv);
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index 6e7a21b..d96280e 100644
--- a/src/rpc/virnetserver.h
+++ b/src/rpc/virnetserver.h
@@ -25,6 +25,9 @@
 # define __VIR_NET_SERVER_H__
 
 # include <signal.h>
+# if HAVE_POLKIT0
+#  include <dbus/dbus.h>
+# endif
 
 # include "virnettlscontext.h"
 # include "virnetserverprogram.h"
@@ -38,6 +41,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
                                 size_t max_workers,
                                 size_t max_clients,
                                 const char *mdnsGroupName,
+                                bool usePolkit,
                                 virNetServerClientInitHook clientInitHook);
 
 typedef int (*virNetServerAutoShutdownFunc)(virNetServerPtr srv, void *opaque);
@@ -46,6 +50,10 @@ void virNetServerRef(virNetServerPtr srv);
 
 bool virNetServerIsPrivileged(virNetServerPtr srv);
 
+# if HAVE_POLKIT0
+DBusConnection* virNetServerGetDBusConn(virNetServerPtr srv);
+# endif
+
 void virNetServerAutoShutdown(virNetServerPtr srv,
                               unsigned int timeout,
                               virNetServerAutoShutdownFunc func,
-- 
1.7.5.4

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]