[Libvir] Deprecated PolicyKit function

Daniel P. Berrange berrange at redhat.com
Mon Feb 18 21:49:44 UTC 2008


On Fri, Feb 15, 2008 at 12:49:03PM +0000, Daniel P. Berrange wrote:
> On Fri, Feb 15, 2008 at 11:03:47AM +0000, Mark McLoughlin wrote:
> > Hi,
> > 	Just a heads-up ... trying to build with -Werror on Fedora rawhide, I
> > see:
> 
> Yep, I've got a patch for this pending - just need to get my rawhide box
> working again to test properly.

The attached patch fixes the deprecation warnings.

It also adds support to the default authentication callback to be able to
invoke polkit-grant or polkit-auth. This allows 'virsh' to obtain auth
from policy kit. The nice thing about doing this via polkit-auth, is that
it will automagically detect if running under X and popup a GUI dialog, or
fallback to using a command line password prompt, while avoiding the need
to link virsh against X.

Second,this moves the virInitialze call into the virConnectOpen methods
instead of do_open - without this the intial DEBUG() calls will never
appear.

Finally it initializes the 'flags' field in the virConnectPtr object
before calling into the drivers, so they see the read only flag without
having to pass it around manually.

Index: configure.in
===================================================================
RCS file: /data/cvs/libvirt/configure.in,v
retrieving revision 1.124
diff -u -p -r1.124 configure.in
--- configure.in	23 Jan 2008 19:37:10 -0000	1.124
+++ configure.in	18 Feb 2008 21:45:11 -0000
@@ -440,6 +440,23 @@ if test "x$with_polkit" = "xyes" -o "x$w
   if test "x$with_polkit" = "xyes" ; then
     AC_DEFINE_UNQUOTED(HAVE_POLKIT, 1,
       [use PolicyKit for UNIX socket access checks])
+
+    old_CFLAGS=$CFLAGS
+    old_LDFLAGS=$LDFLAGS
+    CFLAGS="$CFLAGS $POLKIT_CFLAGS"
+    LDFLAGS="$LDFLAGS $POLKIT_LIBS"
+    AC_CHECK_FUNCS(polkit_context_is_caller_authorized)
+    CFLAGS="$old_CFLAGS"
+    LDFLAGS="$old_LDFLAGS"
+
+    AC_PATH_PROG(POLKIT_GRANT, polkit-grant)
+    if test "x$POLKIT_GRANT" != "x"; then
+      AC_DEFINE_UNQUOTED([POLKIT_GRANT],["$POLKIT_GRANT"],[Location of polkit-grant program])
+    fi
+    AC_PATH_PROG(POLKIT_AUTH, polkit-auth)
+    if test "x$POLKIT_AUTH" != "x"; then
+      AC_DEFINE_UNQUOTED([POLKIT_AUTH],["$POLKIT_AUTH"],[Location of polkit-auth program])
+    fi
   fi
 fi
 AM_CONDITIONAL(HAVE_POLKIT, [test "x$with_polkit" = "xyes"])
Index: qemud/remote.c
===================================================================
RCS file: /data/cvs/libvirt/qemud/remote.c,v
retrieving revision 1.21
diff -u -p -r1.21 remote.c
--- qemud/remote.c	7 Feb 2008 17:03:17 -0000	1.21
+++ qemud/remote.c	18 Feb 2008 21:45:12 -0000
@@ -2616,7 +2616,7 @@ remoteDispatchAuthPolkit (struct qemud_s
         PolKitCaller *pkcaller = NULL;
         PolKitAction *pkaction = NULL;
         PolKitContext *pkcontext = NULL;
-        PolKitError *pkerr;
+        PolKitError *pkerr = NULL;
         PolKitResult pkresult;
         DBusError err;
         const char *action = client->readonly ?
@@ -2658,8 +2658,25 @@ remoteDispatchAuthPolkit (struct qemud_s
             return -2;
         }
 
-        pkresult = polkit_context_can_caller_do_action(pkcontext, pkaction,
+#if HAVE_POLKIT_CONTEXT_IS_CALLER_AUTHORIZED
+        pkresult = polkit_context_is_caller_authorized(pkcontext,
+                                                       pkaction,
+                                                       pkcaller,
+                                                       0,
+                                                       &pkerr);
+        if (pkerr && polkit_error_is_set(pkerr)) {
+            qemudLog(QEMUD_ERR,
+                     "Policy kit failed to check authorization %d %s",
+                     polkit_error_get_error_code(pkerr),
+                     polkit_error_get_error_message(pkerr));
+            remoteDispatchFailAuth(client, req);
+            return -2;
+        }
+#else
+        pkresult = polkit_context_can_caller_do_action(pkcontext,
+                                                       pkaction,
                                                        pkcaller);
+#endif
         polkit_context_unref(pkcontext);
         polkit_caller_unref(pkcaller);
         polkit_action_unref(pkaction);
Index: src/libvirt.c
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt.c,v
retrieving revision 1.120
diff -u -p -r1.120 libvirt.c
--- src/libvirt.c	5 Feb 2008 19:27:37 -0000	1.120
+++ src/libvirt.c	18 Feb 2008 21:45:12 -0000
@@ -33,6 +33,7 @@
 #include "driver.h"
 
 #include "uuid.h"
+#include "util.h"
 #include "test.h"
 #include "xen_unified.h"
 #include "remote_internal.h"
@@ -72,16 +73,38 @@ static int virConnectAuthCallbackDefault
         char *bufptr = buf;
         size_t len;
 
-        if (printf("%s:", cred[i].prompt) < 0)
-            return -1;
-        if (fflush(stdout) != 0)
-            return -1;
-
         switch (cred[i].type) {
+#if defined(POLKIT_GRANT) || defined(POLKIT_AUTH)
+        case VIR_CRED_EXTERNAL: {
+            int ret;
+            const char *const args[] = {
+#if defined(POLKIT_GRANT)
+                POLKIT_GRANT, "--gain", cred[i].prompt, NULL
+#else
+                POLKIT_AUTH, "--obtain", cred[i].prompt, NULL
+#endif
+            };
+
+            if (STRNEQ(cred[i].challenge, "PolicyKit"))
+                return -1;
+            if (virRun(NULL, (char **) args, &ret) < 0)
+                return -1;
+
+            if (!WIFEXITED(ret) ||
+                (WEXITSTATUS(ret) != 0 && WEXITSTATUS(ret) != 1))
+                return -1;
+            break;
+        }
+#endif
         case VIR_CRED_USERNAME:
         case VIR_CRED_AUTHNAME:
         case VIR_CRED_ECHOPROMPT:
         case VIR_CRED_REALM:
+            if (printf("%s:", cred[i].prompt) < 0)
+                return -1;
+            if (fflush(stdout) != 0)
+                return -1;
+
             if (!fgets(buf, sizeof(buf), stdin)) {
                 if (feof(stdin)) { /* Treat EOF as "" */
                     buf[0] = '\0';
@@ -96,6 +119,11 @@ static int virConnectAuthCallbackDefault
 
         case VIR_CRED_PASSPHRASE:
         case VIR_CRED_NOECHOPROMPT:
+            if (printf("%s:", cred[i].prompt) < 0)
+                return -1;
+            if (fflush(stdout) != 0)
+                return -1;
+
             bufptr = getpass("");
             if (!bufptr)
                 return -1;
@@ -127,6 +155,9 @@ static int virConnectCredTypeDefault[] =
     VIR_CRED_REALM,
     VIR_CRED_PASSPHRASE,
     VIR_CRED_NOECHOPROMPT,
+#if defined(POLKIT_AUTH) || defined(POLKIT_GRANT)
+    VIR_CRED_EXTERNAL,
+#endif
 };
 
 static virConnectAuth virConnectAuthDefault = {
@@ -531,10 +562,6 @@ do_open (const char *name,
     if (STREQ (name, "xen://"))
         name = "xen:///";
 
-    if (!initialized)
-        if (virInitialize() < 0)
-	    return NULL;
-
     ret = virGetConnect();
     if (ret == NULL) {
         virLibConnError(NULL, VIR_ERR_NO_MEMORY, _("allocating connection"));
@@ -566,6 +593,9 @@ do_open (const char *name,
         goto failed;
     }
 
+    /* Cleansing flags */
+    ret->flags = flags & VIR_CONNECT_RO;
+
     for (i = 0; i < virDriverTabCount; i++) {
         DEBUG("trying driver %d (%s) ...",
               i, virDriverTab[i]->name);
@@ -607,9 +637,6 @@ do_open (const char *name,
         }
     }
 
-    /* Cleansing flags */
-    ret->flags = flags & VIR_CONNECT_RO;
-
     xmlFreeURI (uri);
 
     return ret;
@@ -635,6 +662,10 @@ failed:
 virConnectPtr
 virConnectOpen (const char *name)
 {
+    if (!initialized)
+        if (virInitialize() < 0)
+            return NULL;
+
     DEBUG("name=%s", name);
     return do_open (name, NULL, 0);
 }
@@ -654,6 +685,10 @@ virConnectOpen (const char *name)
 virConnectPtr
 virConnectOpenReadOnly(const char *name)
 {
+    if (!initialized)
+        if (virInitialize() < 0)
+            return NULL;
+
     DEBUG("name=%s", name);
     return do_open (name, NULL, VIR_CONNECT_RO);
 }
@@ -677,7 +712,11 @@ virConnectOpenAuth(const char *name,
                    virConnectAuthPtr auth,
                    int flags)
 {
-    DEBUG("name=%s", name);
+    if (!initialized)
+        if (virInitialize() < 0)
+            return NULL;
+
+    DEBUG("name=%s, auth=%p, flags=%d", name, auth, flags);
     return do_open (name, auth, flags);
 }
 


Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 




More information about the libvir-list mailing list