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 -=| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list