Daniel P. Berrange 1e6516
diff -rup libvirt-0.4.1.orig/configure.in libvirt-0.4.1.new/configure.in
Daniel P. Berrange 1e6516
--- libvirt-0.4.1.orig/configure.in	2008-03-03 09:14:19.000000000 -0500
Daniel P. Berrange 1e6516
+++ libvirt-0.4.1.new/configure.in	2008-04-03 15:37:49.000000000 -0400
Daniel P. Berrange 1e6516
@@ -450,10 +450,6 @@ if test "x$with_polkit" = "xyes" -o "x$w
Daniel P. Berrange 1e6516
     CFLAGS="$old_CFLAGS"
Daniel P. Berrange 1e6516
     LDFLAGS="$old_LDFLAGS"
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
-    AC_PATH_PROG(POLKIT_GRANT, polkit-grant)
Daniel P. Berrange 1e6516
-    if test "x$POLKIT_GRANT" != "x"; then
Daniel P. Berrange 1e6516
-      AC_DEFINE_UNQUOTED([POLKIT_GRANT],["$POLKIT_GRANT"],[Location of polkit-grant program])
Daniel P. Berrange 1e6516
-    fi
Daniel P. Berrange 1e6516
     AC_PATH_PROG(POLKIT_AUTH, polkit-auth)
Daniel P. Berrange 1e6516
     if test "x$POLKIT_AUTH" != "x"; then
Daniel P. Berrange 1e6516
       AC_DEFINE_UNQUOTED([POLKIT_AUTH],["$POLKIT_AUTH"],[Location of polkit-auth program])
Daniel P. Berrange 1e6516
diff -rup libvirt-0.4.1.orig/qemud/internal.h libvirt-0.4.1.new/qemud/internal.h
Daniel P. Berrange 1e6516
--- libvirt-0.4.1.orig/qemud/internal.h	2008-01-24 12:07:43.000000000 -0500
Daniel P. Berrange 1e6516
+++ libvirt-0.4.1.new/qemud/internal.h	2008-04-03 15:38:03.000000000 -0400
Daniel P. Berrange 1e6516
@@ -179,6 +179,9 @@ void qemudLog(int priority, const char *
Daniel P. Berrange 1e6516
 void remoteDispatchClientRequest (struct qemud_server *server,
Daniel P. Berrange 1e6516
                                   struct qemud_client *client);
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
+#if HAVE_POLKIT
Daniel P. Berrange 1e6516
+int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid);
Daniel P. Berrange 1e6516
+#endif
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
 #endif
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
diff -rup libvirt-0.4.1.orig/qemud/qemud.c libvirt-0.4.1.new/qemud/qemud.c
Daniel P. Berrange 1e6516
--- libvirt-0.4.1.orig/qemud/qemud.c	2008-04-03 15:39:15.000000000 -0400
Daniel P. Berrange 1e6516
+++ libvirt-0.4.1.new/qemud/qemud.c	2008-04-03 15:38:03.000000000 -0400
Daniel P. Berrange 1e6516
@@ -1040,6 +1040,28 @@ remoteCheckAccess (struct qemud_client *
Daniel P. Berrange 1e6516
     return 0;
Daniel P. Berrange 1e6516
 }
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
+#if HAVE_POLKIT
Daniel P. Berrange 1e6516
+int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid) {
Daniel P. Berrange 1e6516
+#ifdef SO_PEERCRED
Daniel P. Berrange 1e6516
+    struct ucred cr;
Daniel P. Berrange 1e6516
+    unsigned int cr_len = sizeof (cr);
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+    if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) < 0) {
Daniel P. Berrange 1e6516
+        qemudLog(QEMUD_ERR, _("Failed to verify client credentials: %s"),
Daniel P. Berrange 1e6516
+                 strerror(errno));
Daniel P. Berrange 1e6516
+        return -1;
Daniel P. Berrange 1e6516
+    }
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+    *pid = cr.pid;
Daniel P. Berrange 1e6516
+    *uid = cr.uid;
Daniel P. Berrange 1e6516
+#else
Daniel P. Berrange 1e6516
+    /* XXX Many more OS support UNIX socket credentials we could port to. See dbus ....*/
Daniel P. Berrange 1e6516
+#error "UNIX socket credentials not supported/implemented on this platform yet..."
Daniel P. Berrange 1e6516
+#endif
Daniel P. Berrange 1e6516
+    return 0;
Daniel P. Berrange 1e6516
+}
Daniel P. Berrange 1e6516
+#endif
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
 static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket *sock) {
Daniel P. Berrange 1e6516
     int fd;
Daniel P. Berrange 1e6516
     struct sockaddr_storage addr;
Daniel P. Berrange 1e6516
@@ -1075,6 +1097,26 @@ static int qemudDispatchServer(struct qe
Daniel P. Berrange 1e6516
     memcpy (&client->addr, &addr, sizeof addr);
Daniel P. Berrange 1e6516
     client->addrlen = addrlen;
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
+#if HAVE_POLKIT
Daniel P. Berrange 1e6516
+    /* Only do policy checks for non-root - allow root user
Daniel P. Berrange 1e6516
+       through with no checks, as a fail-safe - root can easily
Daniel P. Berrange 1e6516
+       change policykit policy anyway, so its pointless trying
Daniel P. Berrange 1e6516
+       to restrict root */
Daniel P. Berrange 1e6516
+    if (client->auth == REMOTE_AUTH_POLKIT) {
Daniel P. Berrange 1e6516
+        uid_t uid;
Daniel P. Berrange 1e6516
+        pid_t pid;
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+        if (qemudGetSocketIdentity(client->fd, &uid, &pid) < 0)
Daniel P. Berrange 1e6516
+            goto cleanup;
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+        /* Cient is running as root, so disable auth */
Daniel P. Berrange 1e6516
+        if (uid == 0) {
Daniel P. Berrange 1e6516
+            qemudLog(QEMUD_INFO, _("Turn off polkit auth for privileged client %d"), pid);
Daniel P. Berrange 1e6516
+            client->auth = REMOTE_AUTH_NONE;
Daniel P. Berrange 1e6516
+        }
Daniel P. Berrange 1e6516
+    }
Daniel P. Berrange 1e6516
+#endif
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
     if (client->type != QEMUD_SOCK_TYPE_TLS) {
Daniel P. Berrange 1e6516
         client->mode = QEMUD_MODE_RX_HEADER;
Daniel P. Berrange 1e6516
         client->bufferLength = REMOTE_MESSAGE_HEADER_XDR_LEN;
Daniel P. Berrange 1e6516
diff -rup libvirt-0.4.1.orig/qemud/remote.c libvirt-0.4.1.new/qemud/remote.c
Daniel P. Berrange 1e6516
--- libvirt-0.4.1.orig/qemud/remote.c	2008-02-29 11:23:17.000000000 -0500
Daniel P. Berrange 1e6516
+++ libvirt-0.4.1.new/qemud/remote.c	2008-04-03 15:38:03.000000000 -0400
Daniel P. Berrange 1e6516
@@ -2564,27 +2564,6 @@ remoteDispatchAuthSaslStep (struct qemud
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
 #if HAVE_POLKIT
Daniel P. Berrange 1e6516
-static int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid) {
Daniel P. Berrange 1e6516
-#ifdef SO_PEERCRED
Daniel P. Berrange 1e6516
-    struct ucred cr;
Daniel P. Berrange 1e6516
-    unsigned int cr_len = sizeof (cr);
Daniel P. Berrange 1e6516
-
Daniel P. Berrange 1e6516
-    if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) < 0) {
Daniel P. Berrange 1e6516
-        qemudLog(QEMUD_ERR, _("Failed to verify client credentials: %s"),
Daniel P. Berrange 1e6516
-                 strerror(errno));
Daniel P. Berrange 1e6516
-        return -1;
Daniel P. Berrange 1e6516
-    }
Daniel P. Berrange 1e6516
-
Daniel P. Berrange 1e6516
-    *pid = cr.pid;
Daniel P. Berrange 1e6516
-    *uid = cr.uid;
Daniel P. Berrange 1e6516
-#else
Daniel P. Berrange 1e6516
-    /* XXX Many more OS support UNIX socket credentials we could port to. See dbus ....*/
Daniel P. Berrange 1e6516
-#error "UNIX socket credentials not supported/implemented on this platform yet..."
Daniel P. Berrange 1e6516
-#endif
Daniel P. Berrange 1e6516
-    return 0;
Daniel P. Berrange 1e6516
-}
Daniel P. Berrange 1e6516
-
Daniel P. Berrange 1e6516
-
Daniel P. Berrange 1e6516
 static int
Daniel P. Berrange 1e6516
 remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
Daniel P. Berrange 1e6516
                           struct qemud_client *client,
Daniel P. Berrange 1e6516
@@ -2594,6 +2573,15 @@ remoteDispatchAuthPolkit (struct qemud_s
Daniel P. Berrange 1e6516
 {
Daniel P. Berrange 1e6516
     pid_t callerPid;
Daniel P. Berrange 1e6516
     uid_t callerUid;
Daniel P. Berrange 1e6516
+    PolKitCaller *pkcaller = NULL;
Daniel P. Berrange 1e6516
+    PolKitAction *pkaction = NULL;
Daniel P. Berrange 1e6516
+    PolKitContext *pkcontext = NULL;
Daniel P. Berrange 1e6516
+    PolKitError *pkerr = NULL;
Daniel P. Berrange 1e6516
+    PolKitResult pkresult;
Daniel P. Berrange 1e6516
+    DBusError err;
Daniel P. Berrange 1e6516
+    const char *action = client->readonly ?
Daniel P. Berrange 1e6516
+        "org.libvirt.unix.monitor" :
Daniel P. Berrange 1e6516
+        "org.libvirt.unix.manage";
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
     REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
Daniel P. Berrange 1e6516
     if (client->auth != REMOTE_AUTH_POLKIT) {
Daniel P. Berrange 1e6516
@@ -2609,98 +2597,78 @@ remoteDispatchAuthPolkit (struct qemud_s
Daniel P. Berrange 1e6516
         return -2;
Daniel P. Berrange 1e6516
     }
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
-    /* Only do policy checks for non-root - allow root user
Daniel P. Berrange 1e6516
-       through with no checks, as a fail-safe - root can easily
Daniel P. Berrange 1e6516
-       change policykit policy anyway, so its pointless trying
Daniel P. Berrange 1e6516
-       to restrict root */
Daniel P. Berrange 1e6516
-    if (callerUid == 0) {
Daniel P. Berrange 1e6516
-        qemudLog(QEMUD_INFO, _("Allowing PID %d running as root"), callerPid);
Daniel P. Berrange 1e6516
-        ret->complete = 1;
Daniel P. Berrange 1e6516
-        client->auth = REMOTE_AUTH_NONE;
Daniel P. Berrange 1e6516
-    } else {
Daniel P. Berrange 1e6516
-        PolKitCaller *pkcaller = NULL;
Daniel P. Berrange 1e6516
-        PolKitAction *pkaction = NULL;
Daniel P. Berrange 1e6516
-        PolKitContext *pkcontext = NULL;
Daniel P. Berrange 1e6516
-        PolKitError *pkerr = NULL;
Daniel P. Berrange 1e6516
-        PolKitResult pkresult;
Daniel P. Berrange 1e6516
-        DBusError err;
Daniel P. Berrange 1e6516
-        const char *action = client->readonly ?
Daniel P. Berrange 1e6516
-            "org.libvirt.unix.monitor" :
Daniel P. Berrange 1e6516
-            "org.libvirt.unix.manage";
Daniel P. Berrange 1e6516
-
Daniel P. Berrange 1e6516
-        qemudLog(QEMUD_INFO, _("Checking PID %d running as %d"),
Daniel P. Berrange 1e6516
-                 callerPid, callerUid);
Daniel P. Berrange 1e6516
-        dbus_error_init(&err;;
Daniel P. Berrange 1e6516
-        if (!(pkcaller = polkit_caller_new_from_pid(server->sysbus,
Daniel P. Berrange 1e6516
-                                                    callerPid, &err))) {
Daniel P. Berrange 1e6516
-            qemudLog(QEMUD_ERR, _("Failed to lookup policy kit caller: %s"),
Daniel P. Berrange 1e6516
-                     err.message);
Daniel P. Berrange 1e6516
-            dbus_error_free(&err;;
Daniel P. Berrange 1e6516
-            remoteDispatchFailAuth(client, req);
Daniel P. Berrange 1e6516
-            return -2;
Daniel P. Berrange 1e6516
-        }
Daniel P. Berrange 1e6516
-
Daniel P. Berrange 1e6516
-        if (!(pkaction = polkit_action_new())) {
Daniel P. Berrange 1e6516
-            qemudLog(QEMUD_ERR, _("Failed to create polkit action %s\n"),
Daniel P. Berrange 1e6516
-                                  strerror(errno));
Daniel P. Berrange 1e6516
-            polkit_caller_unref(pkcaller);
Daniel P. Berrange 1e6516
-            remoteDispatchFailAuth(client, req);
Daniel P. Berrange 1e6516
-            return -2;
Daniel P. Berrange 1e6516
-        }
Daniel P. Berrange 1e6516
-        polkit_action_set_action_id(pkaction, action);
Daniel P. Berrange 1e6516
-
Daniel P. Berrange 1e6516
-        if (!(pkcontext = polkit_context_new()) ||
Daniel P. Berrange 1e6516
-            !polkit_context_init(pkcontext, &pkerr)) {
Daniel P. Berrange 1e6516
-            qemudLog(QEMUD_ERR, _("Failed to create polkit context %s\n"),
Daniel P. Berrange 1e6516
-                     (pkerr ? polkit_error_get_error_message(pkerr)
Daniel P. Berrange 1e6516
-                      : strerror(errno)));
Daniel P. Berrange 1e6516
-            if (pkerr)
Daniel P. Berrange 1e6516
-                polkit_error_free(pkerr);
Daniel P. Berrange 1e6516
-            polkit_caller_unref(pkcaller);
Daniel P. Berrange 1e6516
-            polkit_action_unref(pkaction);
Daniel P. Berrange 1e6516
-            dbus_error_free(&err;;
Daniel P. Berrange 1e6516
-            remoteDispatchFailAuth(client, req);
Daniel P. Berrange 1e6516
-            return -2;
Daniel P. Berrange 1e6516
-        }
Daniel P. Berrange 1e6516
+    qemudLog(QEMUD_INFO, _("Checking PID %d running as %d"),
Daniel P. Berrange 1e6516
+             callerPid, callerUid);
Daniel P. Berrange 1e6516
+    dbus_error_init(&err;;
Daniel P. Berrange 1e6516
+    if (!(pkcaller = polkit_caller_new_from_pid(server->sysbus,
Daniel P. Berrange 1e6516
+                                                callerPid, &err))) {
Daniel P. Berrange 1e6516
+        qemudLog(QEMUD_ERR, _("Failed to lookup policy kit caller: %s"),
Daniel P. Berrange 1e6516
+                 err.message);
Daniel P. Berrange 1e6516
+        dbus_error_free(&err;;
Daniel P. Berrange 1e6516
+        remoteDispatchFailAuth(client, req);
Daniel P. Berrange 1e6516
+        return -2;
Daniel P. Berrange 1e6516
+    }
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+    if (!(pkaction = polkit_action_new())) {
Daniel P. Berrange 1e6516
+        qemudLog(QEMUD_ERR, _("Failed to create polkit action %s\n"),
Daniel P. Berrange 1e6516
+                 strerror(errno));
Daniel P. Berrange 1e6516
+        polkit_caller_unref(pkcaller);
Daniel P. Berrange 1e6516
+        remoteDispatchFailAuth(client, req);
Daniel P. Berrange 1e6516
+        return -2;
Daniel P. Berrange 1e6516
+    }
Daniel P. Berrange 1e6516
+    polkit_action_set_action_id(pkaction, action);
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+    if (!(pkcontext = polkit_context_new()) ||
Daniel P. Berrange 1e6516
+        !polkit_context_init(pkcontext, &pkerr)) {
Daniel P. Berrange 1e6516
+        qemudLog(QEMUD_ERR, _("Failed to create polkit context %s\n"),
Daniel P. Berrange 1e6516
+                 (pkerr ? polkit_error_get_error_message(pkerr)
Daniel P. Berrange 1e6516
+                  : strerror(errno)));
Daniel P. Berrange 1e6516
+        if (pkerr)
Daniel P. Berrange 1e6516
+            polkit_error_free(pkerr);
Daniel P. Berrange 1e6516
+        polkit_caller_unref(pkcaller);
Daniel P. Berrange 1e6516
+        polkit_action_unref(pkaction);
Daniel P. Berrange 1e6516
+        dbus_error_free(&err;;
Daniel P. Berrange 1e6516
+        remoteDispatchFailAuth(client, req);
Daniel P. Berrange 1e6516
+        return -2;
Daniel P. Berrange 1e6516
+    }
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
 #if HAVE_POLKIT_CONTEXT_IS_CALLER_AUTHORIZED
Daniel P. Berrange 1e6516
-        pkresult = polkit_context_is_caller_authorized(pkcontext,
Daniel P. Berrange 1e6516
-                                                       pkaction,
Daniel P. Berrange 1e6516
-                                                       pkcaller,
Daniel P. Berrange 1e6516
-                                                       0,
Daniel P. Berrange 1e6516
-                                                       &pkerr);
Daniel P. Berrange 1e6516
-        if (pkerr && polkit_error_is_set(pkerr)) {
Daniel P. Berrange 1e6516
-            qemudLog(QEMUD_ERR,
Daniel P. Berrange 1e6516
-                     _("Policy kit failed to check authorization %d %s"),
Daniel P. Berrange 1e6516
-                     polkit_error_get_error_code(pkerr),
Daniel P. Berrange 1e6516
-                     polkit_error_get_error_message(pkerr));
Daniel P. Berrange 1e6516
-            remoteDispatchFailAuth(client, req);
Daniel P. Berrange 1e6516
-            return -2;
Daniel P. Berrange 1e6516
-        }
Daniel P. Berrange 1e6516
+    pkresult = polkit_context_is_caller_authorized(pkcontext,
Daniel P. Berrange 1e6516
+                                                   pkaction,
Daniel P. Berrange 1e6516
+                                                   pkcaller,
Daniel P. Berrange 1e6516
+                                                   0,
Daniel P. Berrange 1e6516
+                                                   &pkerr);
Daniel P. Berrange 1e6516
+    if (pkerr && polkit_error_is_set(pkerr)) {
Daniel P. Berrange 1e6516
+        qemudLog(QEMUD_ERR,
Daniel P. Berrange 1e6516
+                 _("Policy kit failed to check authorization %d %s"),
Daniel P. Berrange 1e6516
+                 polkit_error_get_error_code(pkerr),
Daniel P. Berrange 1e6516
+                 polkit_error_get_error_message(pkerr));
Daniel P. Berrange 1e6516
+        remoteDispatchFailAuth(client, req);
Daniel P. Berrange 1e6516
+        return -2;
Daniel P. Berrange 1e6516
+    }
Daniel P. Berrange 1e6516
 #else
Daniel P. Berrange 1e6516
-        pkresult = polkit_context_can_caller_do_action(pkcontext,
Daniel P. Berrange 1e6516
-                                                       pkaction,
Daniel P. Berrange 1e6516
-                                                       pkcaller);
Daniel P. Berrange 1e6516
+    pkresult = polkit_context_can_caller_do_action(pkcontext,
Daniel P. Berrange 1e6516
+                                                   pkaction,
Daniel P. Berrange 1e6516
+                                                   pkcaller);
Daniel P. Berrange 1e6516
 #endif
Daniel P. Berrange 1e6516
-        polkit_context_unref(pkcontext);
Daniel P. Berrange 1e6516
-        polkit_caller_unref(pkcaller);
Daniel P. Berrange 1e6516
-        polkit_action_unref(pkaction);
Daniel P. Berrange 1e6516
-        if (pkresult != POLKIT_RESULT_YES) {
Daniel P. Berrange 1e6516
-            qemudLog(QEMUD_ERR,
Daniel P. Berrange 1e6516
-                     _("Policy kit denied action %s from pid %d, uid %d,"
Daniel P. Berrange 1e6516
-                       " result: %s\n"),
Daniel P. Berrange 1e6516
-                     action, callerPid, callerUid,
Daniel P. Berrange 1e6516
-                     polkit_result_to_string_representation(pkresult));
Daniel P. Berrange 1e6516
-            remoteDispatchFailAuth(client, req);
Daniel P. Berrange 1e6516
-            return -2;
Daniel P. Berrange 1e6516
-        }
Daniel P. Berrange 1e6516
-        qemudLog(QEMUD_INFO,
Daniel P. Berrange 1e6516
-                 _("Policy allowed action %s from pid %d, uid %d, result %s"),
Daniel P. Berrange 1e6516
+    polkit_context_unref(pkcontext);
Daniel P. Berrange 1e6516
+    polkit_caller_unref(pkcaller);
Daniel P. Berrange 1e6516
+    polkit_action_unref(pkaction);
Daniel P. Berrange 1e6516
+    if (pkresult != POLKIT_RESULT_YES) {
Daniel P. Berrange 1e6516
+        qemudLog(QEMUD_ERR,
Daniel P. Berrange 1e6516
+                 _("Policy kit denied action %s from pid %d, uid %d,"
Daniel P. Berrange 1e6516
+                   " result: %s\n"),
Daniel P. Berrange 1e6516
                  action, callerPid, callerUid,
Daniel P. Berrange 1e6516
                  polkit_result_to_string_representation(pkresult));
Daniel P. Berrange 1e6516
-        ret->complete = 1;
Daniel P. Berrange 1e6516
-        client->auth = REMOTE_AUTH_NONE;
Daniel P. Berrange 1e6516
+        remoteDispatchFailAuth(client, req);
Daniel P. Berrange 1e6516
+        return -2;
Daniel P. Berrange 1e6516
     }
Daniel P. Berrange 1e6516
+    qemudLog(QEMUD_INFO,
Daniel P. Berrange 1e6516
+             _("Policy allowed action %s from pid %d, uid %d, result %s"),
Daniel P. Berrange 1e6516
+             action, callerPid, callerUid,
Daniel P. Berrange 1e6516
+             polkit_result_to_string_representation(pkresult));
Daniel P. Berrange 1e6516
+    ret->complete = 1;
Daniel P. Berrange 1e6516
+    client->auth = REMOTE_AUTH_NONE;
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
     return 0;
Daniel P. Berrange 1e6516
 }
Daniel P. Berrange 1e6516
diff -rup libvirt-0.4.1.orig/src/libvirt.c libvirt-0.4.1.new/src/libvirt.c
Daniel P. Berrange 1e6516
--- libvirt-0.4.1.orig/src/libvirt.c	2008-02-26 10:37:43.000000000 -0500
Daniel P. Berrange 1e6516
+++ libvirt-0.4.1.new/src/libvirt.c	2008-04-03 15:38:47.000000000 -0400
Daniel P. Berrange 1e6516
@@ -19,6 +19,9 @@
Daniel P. Berrange 1e6516
 #include <sys/stat.h>
Daniel P. Berrange 1e6516
 #include <unistd.h>
Daniel P. Berrange 1e6516
 #include <assert.h>
Daniel P. Berrange 1e6516
+#ifdef HAVE_SYS_WAIT_H
Daniel P. Berrange 1e6516
+#include <sys/wait.h>
Daniel P. Berrange 1e6516
+#endif
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
 #include <libxml/parser.h>
Daniel P. Berrange 1e6516
 #include <libxml/xpath.h>
Daniel P. Berrange 1e6516
@@ -66,6 +69,39 @@ static int initialized = 0;
Daniel P. Berrange 1e6516
 int debugFlag = 0;
Daniel P. Berrange 1e6516
 #endif
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
+#if defined(POLKIT_AUTH)
Daniel P. Berrange 1e6516
+static int virConnectAuthGainPolkit(const char *privilege) {
Daniel P. Berrange 1e6516
+    const char *const args[] = {
Daniel P. Berrange 1e6516
+        POLKIT_AUTH, "--obtain", privilege, NULL
Daniel P. Berrange 1e6516
+    };
Daniel P. Berrange 1e6516
+    int childpid, status, ret;
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+    /* Root has all rights */
Daniel P. Berrange 1e6516
+    if (getuid() == 0)
Daniel P. Berrange 1e6516
+        return 0;
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+    if ((childpid = fork()) < 0)
Daniel P. Berrange 1e6516
+        return -1;
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+    if (!childpid) {
Daniel P. Berrange 1e6516
+        execvp(args[0], (char **)args);
Daniel P. Berrange 1e6516
+        _exit(-1);
Daniel P. Berrange 1e6516
+    }
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+    while ((ret = waitpid(childpid, &status, 0) == -1) && errno == EINTR);
Daniel P. Berrange 1e6516
+    if (ret == -1) {
Daniel P. Berrange 1e6516
+        return -1;
Daniel P. Berrange 1e6516
+    }
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+    if (!WIFEXITED(status) ||
Daniel P. Berrange 1e6516
+        (WEXITSTATUS(status) != 0 && WEXITSTATUS(status) != 1)) {
Daniel P. Berrange 1e6516
+        return -1;
Daniel P. Berrange 1e6516
+    }
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
+    return 0;
Daniel P. Berrange 1e6516
+}
Daniel P. Berrange 1e6516
+#endif
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
 static int virConnectAuthCallbackDefault(virConnectCredentialPtr cred,
Daniel P. Berrange 1e6516
                                          unsigned int ncred,
Daniel P. Berrange 1e6516
                                          void *cbdata ATTRIBUTE_UNUSED) {
Daniel P. Berrange 1e6516
@@ -77,28 +113,25 @@ static int virConnectAuthCallbackDefault
Daniel P. Berrange 1e6516
         size_t len;
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
         switch (cred[i].type) {
Daniel P. Berrange 1e6516
-#if defined(POLKIT_GRANT) || defined(POLKIT_AUTH)
Daniel P. Berrange 1e6516
         case VIR_CRED_EXTERNAL: {
Daniel P. Berrange 1e6516
             int ret;
Daniel P. Berrange 1e6516
-            const char *const args[] = {
Daniel P. Berrange 1e6516
-#if defined(POLKIT_GRANT)
Daniel P. Berrange 1e6516
-                POLKIT_GRANT, "--gain", cred[i].prompt, NULL
Daniel P. Berrange 1e6516
-#else
Daniel P. Berrange 1e6516
-                POLKIT_AUTH, "--obtain", cred[i].prompt, NULL
Daniel P. Berrange 1e6516
-#endif
Daniel P. Berrange 1e6516
-            };
Daniel P. Berrange 1e6516
-
Daniel P. Berrange 1e6516
             if (STRNEQ(cred[i].challenge, "PolicyKit"))
Daniel P. Berrange 1e6516
                 return -1;
Daniel P. Berrange 1e6516
-            if (virRun(NULL, (char **) args, &ret) < 0)
Daniel P. Berrange 1e6516
-                return -1;
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
-            if (!WIFEXITED(ret) ||
Daniel P. Berrange 1e6516
-                (WEXITSTATUS(ret) != 0 && WEXITSTATUS(ret) != 1))
Daniel P. Berrange 1e6516
+#if defined(POLKIT_AUTH)
Daniel P. Berrange 1e6516
+            if (virConnectAuthGainPolkit(cred[i].prompt) < 0)
Daniel P. Berrange 1e6516
                 return -1;
Daniel P. Berrange 1e6516
+#else
Daniel P. Berrange 1e6516
+            /*
Daniel P. Berrange 1e6516
+             * Ignore & carry on. Although we can't auth
Daniel P. Berrange 1e6516
+             * directly, the user may have authenticated
Daniel P. Berrange 1e6516
+             * themselves already outside context of libvirt
Daniel P. Berrange 1e6516
+             */
Daniel P. Berrange 1e6516
+#endif
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
             break;
Daniel P. Berrange 1e6516
         }
Daniel P. Berrange 1e6516
-#endif
Daniel P. Berrange 1e6516
+
Daniel P. Berrange 1e6516
         case VIR_CRED_USERNAME:
Daniel P. Berrange 1e6516
         case VIR_CRED_AUTHNAME:
Daniel P. Berrange 1e6516
         case VIR_CRED_ECHOPROMPT:
Daniel P. Berrange 1e6516
@@ -158,9 +191,7 @@ static int virConnectCredTypeDefault[] =
Daniel P. Berrange 1e6516
     VIR_CRED_REALM,
Daniel P. Berrange 1e6516
     VIR_CRED_PASSPHRASE,
Daniel P. Berrange 1e6516
     VIR_CRED_NOECHOPROMPT,
Daniel P. Berrange 1e6516
-#if defined(POLKIT_AUTH) || defined(POLKIT_GRANT)
Daniel P. Berrange 1e6516
     VIR_CRED_EXTERNAL,
Daniel P. Berrange 1e6516
-#endif
Daniel P. Berrange 1e6516
 };
Daniel P. Berrange 1e6516
 
Daniel P. Berrange 1e6516
 static virConnectAuth virConnectAuthDefault = {