[libvirt] [PATCH v3 0/3] Add capability for text based polkit authentication for virsh

v2: http://www.redhat.com/archives/libvir-list/2016-February/msg00618.html Adjustments since v2: Patch 1 - Change not only the message (as requested), but also use a different and new error code (VIR_ERR_AUTH_UNAVAILABLE). Patch 2 - Added a check for "if (!isatty(STDIN_FILENO))" Used a new parameter for pkttyagent call - "--notify-fd", which is documented as "To get notified when the authentication agent has been registered either listen to the Changed D-Bus signal or use --notify-fd to pass the number of a file descriptor that has been passed to the program. This file descriptor will then be closed when the authentication agent has been successfully registered. Followed the systemd mechanism. If it's felt that a timeout of -1 is too dangerous, I'd be fine with changing it. Patch 3 - Since we now can determine our failure based on err->code, use the new VIR_ERR_AUTH_UNAVAILABLE to attempt the AgentCreate. Also, since virPolkitAgentCreate now will wait for the agent to start before returning, the agentstart counter is removed. John Ferlan (3): polkit: Adjust message when authentication agent isn't found util: Introduce API's for Polkit text authentication virsh: Add support for text based polkit authentication include/libvirt/virterror.h | 3 +- src/libvirt_private.syms | 2 ++ src/util/virerror.c | 8 ++++- src/util/virpolkit.c | 85 ++++++++++++++++++++++++++++++++++++++++++--- src/util/virpolkit.h | 5 +++ tests/virpolkittest.c | 8 +++-- tools/virsh.c | 38 +++++++++++++++++--- tools/virsh.h | 2 ++ 8 files changed, 138 insertions(+), 13 deletions(-) -- 2.5.0

When there isn't a ssh -X type session running and a user has not been added to the libvirt group, attempts to run 'virsh -c qemu:///system' commands from an otherwise unprivileged user will fail with rather generic or opaque error message: "error: authentication failed: no agent is available to authenticate" This patch will adjust the error code and message to help reflect the situation that the problem is the requested mechanism is UNAVAILABLE and a slightly more descriptive error. The result on a failure then becomes: "error: authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage'" A bit more history on this - at one time a failure generated the following type message when running the 'pkcheck' as a subprocess: "error: authentication failed: polkit\56retains_authorization_after_challenge=1 Authorization requires authentication but no agent is available." but, a patch was generated to adjust the error message to help provide more details about what failed. This was pushed as commit id '96a108c99'. That patch prepended a "polkit: " to the output. It really didn't solve the problem, but gave a hint. After some time it was deemed using DBus API calls directly was a better way to go (since pkcheck calls them anyway). So, commit id '1b854c76' (more or less) copied the code from remoteDispatchAuthPolkit and adjusted it. Then commit id 'c7542573' adjusted the remote.c code to call the new API (virPolkitCheckAuth). Finally, commit id '308c0c5a' altered the code to call DBus APIs directly. In doing so, it reverted the failing error message to the generic message that would have been received from DBus anyway. Signed-off-by: John Ferlan <jferlan@redhat.com> --- include/libvirt/virterror.h | 3 ++- src/util/virerror.c | 8 +++++++- src/util/virpolkit.c | 8 +++++--- tests/virpolkittest.c | 7 ++++--- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index c6d1a76..83f76d8 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -4,7 +4,7 @@ * Description: Provides the interfaces of the libvirt library to handle * errors raised while using the library. * - * Copyright (C) 2006-2015 Red Hat, Inc. + * Copyright (C) 2006-2016 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -310,6 +310,7 @@ typedef enum { CPU*/ VIR_ERR_XML_INVALID_SCHEMA = 92, /* XML document doesn't validate against schema */ VIR_ERR_MIGRATE_FINISH_OK = 93, /* Finish API succeeded but it is expected to return NULL */ + VIR_ERR_AUTH_UNAVAILABLE = 94, /* authentication unavailable */ } virErrorNumber; /** diff --git a/src/util/virerror.c b/src/util/virerror.c index 3a3ddef..839a413 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -1,7 +1,7 @@ /* * virerror.c: error handling and reporting code for libvirt * - * Copyright (C) 2006, 2008-2015 Red Hat, Inc. + * Copyright (C) 2006, 2008-2016 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1095,6 +1095,12 @@ virErrorMsg(virErrorNumber error, const char *info) else errmsg = _("authentication cancelled: %s"); break; + case VIR_ERR_AUTH_UNAVAILABLE: + if (info == NULL) + errmsg = _("authentication unavailable"); + else + errmsg = _("authentication unavailable: %s"); + break; case VIR_ERR_NO_STORAGE_POOL: if (info == NULL) errmsg = _("Storage pool not found"); diff --git a/src/util/virpolkit.c b/src/util/virpolkit.c index 8da91f2..df707f1 100644 --- a/src/util/virpolkit.c +++ b/src/util/virpolkit.c @@ -1,7 +1,7 @@ /* * virpolkit.c: helpers for using polkit APIs * - * Copyright (C) 2013, 2014 Red Hat, Inc. + * Copyright (C) 2013, 2014, 2016 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -121,8 +121,10 @@ int virPolkitCheckAuth(const char *actionid, virReportError(VIR_ERR_AUTH_CANCELLED, "%s", _("user cancelled authentication process")); else if (is_challenge) - virReportError(VIR_ERR_AUTH_FAILED, "%s", - _("no agent is available to authenticate")); + virReportError(VIR_ERR_AUTH_UNAVAILABLE, + _("no polkit agent available to authenticate " + "action '%s'"), + actionid); else virReportError(VIR_ERR_AUTH_FAILED, "%s", _("access denied by policy")); diff --git a/tests/virpolkittest.c b/tests/virpolkittest.c index 1ef7635..73f001b 100644 --- a/tests/virpolkittest.c +++ b/tests/virpolkittest.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013, 2014 Red Hat, Inc. + * Copyright (C) 2013, 2014, 2016 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -220,8 +220,9 @@ static int testPolkitAuthChallenge(const void *opaque ATTRIBUTE_UNUSED) } err = virGetLastError(); - if (!err || !strstr(err->message, - _("no agent is available to authenticate"))) { + if (!err || err->domain != VIR_FROM_POLKIT || + err->code != VIR_ERR_AUTH_UNAVAILABLE || + !strstr(err->message, _("no polkit agent available to authenticate"))) { fprintf(stderr, "Incorrect error response\n"); goto cleanup; } -- 2.5.0

On Fri, Feb 12, 2016 at 12:12:31PM -0500, John Ferlan wrote:
When there isn't a ssh -X type session running and a user has not been added to the libvirt group, attempts to run 'virsh -c qemu:///system' commands from an otherwise unprivileged user will fail with rather generic or opaque error message:
"error: authentication failed: no agent is available to authenticate"
This patch will adjust the error code and message to help reflect the situation that the problem is the requested mechanism is UNAVAILABLE and a slightly more descriptive error. The result on a failure then becomes:
"error: authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage'"
A bit more history on this - at one time a failure generated the following type message when running the 'pkcheck' as a subprocess:
"error: authentication failed: polkit\56retains_authorization_after_challenge=1 Authorization requires authentication but no agent is available."
but, a patch was generated to adjust the error message to help provide more details about what failed. This was pushed as commit id '96a108c99'. That patch prepended a "polkit: " to the output. It really didn't solve the problem, but gave a hint.
After some time it was deemed using DBus API calls directly was a better way to go (since pkcheck calls them anyway). So, commit id '1b854c76' (more or less) copied the code from remoteDispatchAuthPolkit and adjusted it. Then commit id 'c7542573' adjusted the remote.c code to call the new API (virPolkitCheckAuth). Finally, commit id '308c0c5a' altered the code to call DBus APIs directly. In doing so, it reverted the failing error message to the generic message that would have been received from DBus anyway.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- include/libvirt/virterror.h | 3 ++- src/util/virerror.c | 8 +++++++- src/util/virpolkit.c | 8 +++++--- tests/virpolkittest.c | 7 ++++--- 4 files changed, 18 insertions(+), 8 deletions(-)
ACK Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Introduce virPolkitAgentCreate and virPolkitAgentDestroy virPolkitAgentCreate will run the polkit pkttyagent image as an asynchronous command in order to handle the local agent authentication via stdin/stdout. The code makes use of the pkttyagent --notify-fd mechanism to let it know when the agent is successfully registered. virPolkitAgentDestroy will close the command effectively reaping our child process Needed to move around or add the "#include vircommand.h" since, virpolkit.h now uses it. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/libvirt_private.syms | 2 ++ src/util/virpolkit.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++- src/util/virpolkit.h | 5 ++++ tests/virpolkittest.c | 1 + 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4cfaed5..8f2358f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2029,6 +2029,8 @@ virPidFileWritePath; # util/virpolkit.h +virPolkitAgentCreate; +virPolkitAgentDestroy; virPolkitCheckAuth; diff --git a/src/util/virpolkit.c b/src/util/virpolkit.c index df707f1..6941d74 100644 --- a/src/util/virpolkit.c +++ b/src/util/virpolkit.c @@ -20,20 +20,22 @@ */ #include <config.h> +#include <poll.h> #if WITH_POLKIT0 # include <polkit/polkit.h> # include <polkit-dbus/polkit-dbus.h> #endif -#include "virpolkit.h" #include "vircommand.h" +#include "virpolkit.h" #include "virerror.h" #include "virlog.h" #include "virstring.h" #include "virprocess.h" #include "viralloc.h" #include "virdbus.h" +#include "virfile.h" #define VIR_FROM_THIS VIR_FROM_POLKIT @@ -136,6 +138,65 @@ int virPolkitCheckAuth(const char *actionid, } +/* virPolkitAgentDestroy: + * @cmd: Pointer to the virCommandPtr created during virPolkitAgentCreate + * + * Destroy resources used by Polkit Agent + */ +void +virPolkitAgentDestroy(virCommandPtr cmd) +{ + virCommandFree(cmd); +} + +/* virPolkitAgentCreate: + * + * Allocate and setup a polkit agent + * + * Returns a virCommandPtr on success and NULL on failure + */ +virCommandPtr +virPolkitAgentCreate(void) +{ + virCommandPtr cmd = virCommandNewArgList(PKTTYAGENT, "--process", NULL); + int pipe_fd[2] = {-1, -1}; + struct pollfd pollfd; + int outfd = STDOUT_FILENO; + int errfd = STDERR_FILENO; + + if (!isatty(STDIN_FILENO)) + goto error; + + if (pipe2(pipe_fd, 0) < 0) + goto error; + + virCommandAddArgFormat(cmd, "%lld", (long long int) getpid()); + virCommandAddArg(cmd, "--notify-fd"); + virCommandAddArgFormat(cmd, "%d", pipe_fd[1]); + virCommandAddArg(cmd, "--fallback"); + virCommandSetInputFD(cmd, STDIN_FILENO); + virCommandSetOutputFD(cmd, &outfd); + virCommandSetErrorFD(cmd, &errfd); + virCommandPassFD(cmd, pipe_fd[1], VIR_COMMAND_PASS_FD_CLOSE_PARENT); + if (virCommandRunAsync(cmd, NULL) < 0) + goto error; + + pollfd.fd = pipe_fd[0]; + pollfd.events = POLLHUP; + + if (poll(&pollfd, 1, -1) < 0) + goto error; + + return cmd; + + error: + VIR_FORCE_CLOSE(pipe_fd[0]); + VIR_FORCE_CLOSE(pipe_fd[1]); + virCommandFree(cmd); + return NULL; +} + + #elif WITH_POLKIT0 int virPolkitCheckAuth(const char *actionid, pid_t pid, @@ -254,4 +315,18 @@ int virPolkitCheckAuth(const char *actionid ATTRIBUTE_UNUSED, } +void +virPolkitAgentDestroy(virCommandPtr cmd ATTRIBUTE_UNUSED) +{ + return; /* do nothing */ +} + + +virCommandPtr +virPolkitAgentCreate(void) +{ + virReportError(VIR_ERR_AUTH_FAILED, "%s", + _("polkit text authentication agent unavailable")); + return NULL; +} #endif /* WITH_POLKIT1 */ diff --git a/src/util/virpolkit.h b/src/util/virpolkit.h index 36122d0..f0aea37 100644 --- a/src/util/virpolkit.h +++ b/src/util/virpolkit.h @@ -24,6 +24,8 @@ # include "internal.h" +# define PKTTYAGENT "/usr/bin/pkttyagent" + int virPolkitCheckAuth(const char *actionid, pid_t pid, unsigned long long startTime, @@ -31,4 +33,7 @@ int virPolkitCheckAuth(const char *actionid, const char **details, bool allowInteraction); +void virPolkitAgentDestroy(virCommandPtr cmd); +virCommandPtr virPolkitAgentCreate(void); + #endif /* __VIR_POLKIT_H__ */ diff --git a/tests/virpolkittest.c b/tests/virpolkittest.c index 73f001b..b46e65f 100644 --- a/tests/virpolkittest.c +++ b/tests/virpolkittest.c @@ -27,6 +27,7 @@ # include <stdlib.h> # include <dbus/dbus.h> +# include "vircommand.h" # include "virpolkit.h" # include "virdbus.h" # include "virlog.h" -- 2.5.0

On Fri, Feb 12, 2016 at 12:12:32PM -0500, John Ferlan wrote:
Introduce virPolkitAgentCreate and virPolkitAgentDestroy
virPolkitAgentCreate will run the polkit pkttyagent image as an asynchronous command in order to handle the local agent authentication via stdin/stdout. The code makes use of the pkttyagent --notify-fd mechanism to let it know when the agent is successfully registered.
virPolkitAgentDestroy will close the command effectively reaping our child process
Needed to move around or add the "#include vircommand.h" since, virpolkit.h now uses it.
I have literally no idea how PolicyKit is used, so I don't feel like the right person to review more than the first patch (which looks fine). But this is something I can't let go unnoticed, sorry. If you are using virCommandPtr in virpolkit.h, then that file should also include vircommand.h. Then you can remove it from virpolkit.c (if it is included there) and you don't need to reorganize the includes or touch them in other files. And anyone can include virpolkit.h without needing to care about any dependencies.

On 02/22/2016 10:41 AM, Martin Kletzander wrote:
On Fri, Feb 12, 2016 at 12:12:32PM -0500, John Ferlan wrote:
Introduce virPolkitAgentCreate and virPolkitAgentDestroy
virPolkitAgentCreate will run the polkit pkttyagent image as an asynchronous command in order to handle the local agent authentication via stdin/stdout. The code makes use of the pkttyagent --notify-fd mechanism to let it know when the agent is successfully registered.
virPolkitAgentDestroy will close the command effectively reaping our child process
Needed to move around or add the "#include vircommand.h" since, virpolkit.h now uses it.
I have literally no idea how PolicyKit is used, so I don't feel like the right person to review more than the first patch (which looks fine).
Understood - part of the first patch did get an ACK in v2; however, since I updated it to use VIR_ERR_AUTH_UNAVAILABLE (based on other review comments), I figured it was best to send it out for review.
But this is something I can't let go unnoticed, sorry. If you are using virCommandPtr in virpolkit.h, then that file should also include vircommand.h. Then you can remove it from virpolkit.c (if it is included there) and you don't need to reorganize the includes or touch them in other files. And anyone can include virpolkit.h without needing to care about any dependencies.
Oh - right... I moved the include of vircommand.h into virpolkit.h. That means removing it from virpolkit.c on this patch and virsh.h on the next patch. Tks - John

On Fri, Feb 12, 2016 at 12:12:32PM -0500, John Ferlan wrote:
Introduce virPolkitAgentCreate and virPolkitAgentDestroy
virPolkitAgentCreate will run the polkit pkttyagent image as an asynchronous command in order to handle the local agent authentication via stdin/stdout. The code makes use of the pkttyagent --notify-fd mechanism to let it know when the agent is successfully registered.
virPolkitAgentDestroy will close the command effectively reaping our child process
Needed to move around or add the "#include vircommand.h" since, virpolkit.h now uses it.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/libvirt_private.syms | 2 ++ src/util/virpolkit.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++- src/util/virpolkit.h | 5 ++++ tests/virpolkittest.c | 1 + 4 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4cfaed5..8f2358f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2029,6 +2029,8 @@ virPidFileWritePath;
# util/virpolkit.h +virPolkitAgentCreate; +virPolkitAgentDestroy; virPolkitCheckAuth;
diff --git a/src/util/virpolkit.c b/src/util/virpolkit.c index df707f1..6941d74 100644 --- a/src/util/virpolkit.c +++ b/src/util/virpolkit.c @@ -20,20 +20,22 @@ */
#include <config.h> +#include <poll.h>
#if WITH_POLKIT0 # include <polkit/polkit.h> # include <polkit-dbus/polkit-dbus.h> #endif
-#include "virpolkit.h" #include "vircommand.h" +#include "virpolkit.h" #include "virerror.h" #include "virlog.h" #include "virstring.h" #include "virprocess.h" #include "viralloc.h" #include "virdbus.h" +#include "virfile.h"
#define VIR_FROM_THIS VIR_FROM_POLKIT
@@ -136,6 +138,65 @@ int virPolkitCheckAuth(const char *actionid, }
+/* virPolkitAgentDestroy: + * @cmd: Pointer to the virCommandPtr created during virPolkitAgentCreate + * + * Destroy resources used by Polkit Agent + */ +void +virPolkitAgentDestroy(virCommandPtr cmd) +{ + virCommandFree(cmd); +} + +/* virPolkitAgentCreate: + * + * Allocate and setup a polkit agent + * + * Returns a virCommandPtr on success and NULL on failure + */ +virCommandPtr +virPolkitAgentCreate(void) +{ + virCommandPtr cmd = virCommandNewArgList(PKTTYAGENT, "--process", NULL); + int pipe_fd[2] = {-1, -1}; + struct pollfd pollfd; + int outfd = STDOUT_FILENO; + int errfd = STDERR_FILENO; + + if (!isatty(STDIN_FILENO)) + goto error; + + if (pipe2(pipe_fd, 0) < 0) + goto error; + + virCommandAddArgFormat(cmd, "%lld", (long long int) getpid()); + virCommandAddArg(cmd, "--notify-fd"); + virCommandAddArgFormat(cmd, "%d", pipe_fd[1]); + virCommandAddArg(cmd, "--fallback"); + virCommandSetInputFD(cmd, STDIN_FILENO); + virCommandSetOutputFD(cmd, &outfd); + virCommandSetErrorFD(cmd, &errfd); + virCommandPassFD(cmd, pipe_fd[1], VIR_COMMAND_PASS_FD_CLOSE_PARENT); + if (virCommandRunAsync(cmd, NULL) < 0) + goto error; + + pollfd.fd = pipe_fd[0]; + pollfd.events = POLLHUP; + + if (poll(&pollfd, 1, -1) < 0) + goto error; + + return cmd; + + error: + VIR_FORCE_CLOSE(pipe_fd[0]); + VIR_FORCE_CLOSE(pipe_fd[1]); + virCommandFree(cmd); + return NULL; +} + + #elif WITH_POLKIT0 int virPolkitCheckAuth(const char *actionid, pid_t pid, @@ -254,4 +315,18 @@ int virPolkitCheckAuth(const char *actionid ATTRIBUTE_UNUSED, }
+void +virPolkitAgentDestroy(virCommandPtr cmd ATTRIBUTE_UNUSED) +{ + return; /* do nothing */ +} + + +virCommandPtr +virPolkitAgentCreate(void) +{ + virReportError(VIR_ERR_AUTH_FAILED, "%s", + _("polkit text authentication agent unavailable")); + return NULL; +} #endif /* WITH_POLKIT1 */ diff --git a/src/util/virpolkit.h b/src/util/virpolkit.h index 36122d0..f0aea37 100644 --- a/src/util/virpolkit.h +++ b/src/util/virpolkit.h @@ -24,6 +24,8 @@
# include "internal.h"
+# define PKTTYAGENT "/usr/bin/pkttyagent" + int virPolkitCheckAuth(const char *actionid, pid_t pid, unsigned long long startTime, @@ -31,4 +33,7 @@ int virPolkitCheckAuth(const char *actionid, const char **details, bool allowInteraction);
+void virPolkitAgentDestroy(virCommandPtr cmd); +virCommandPtr virPolkitAgentCreate(void);
Rather than exposing use of virCommand in the API, I'd suggest you create a typedef struct virPolkitAgent virPolkitAgent; typedef virPolkitAgent *virPolkitAgentPtr; in the header file here and in the .c do struct virPolitAgent { virCommandPtr; }; so we hide use of virCommand
diff --git a/tests/virpolkittest.c b/tests/virpolkittest.c index 73f001b..b46e65f 100644 --- a/tests/virpolkittest.c +++ b/tests/virpolkittest.c @@ -27,6 +27,7 @@ # include <stdlib.h> # include <dbus/dbus.h>
+# include "vircommand.h"
avoiding this Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 02/25/2016 09:25 AM, Daniel P. Berrange wrote:
On Fri, Feb 12, 2016 at 12:12:32PM -0500, John Ferlan wrote:
Introduce virPolkitAgentCreate and virPolkitAgentDestroy
virPolkitAgentCreate will run the polkit pkttyagent image as an asynchronous command in order to handle the local agent authentication via stdin/stdout. The code makes use of the pkttyagent --notify-fd mechanism to let it know when the agent is successfully registered.
virPolkitAgentDestroy will close the command effectively reaping our child process
Needed to move around or add the "#include vircommand.h" since, virpolkit.h now uses it.
This part of the commit message was removed with Martin's request/change.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/libvirt_private.syms | 2 ++ src/util/virpolkit.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++- src/util/virpolkit.h | 5 ++++ tests/virpolkittest.c | 1 + 4 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4cfaed5..8f2358f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2029,6 +2029,8 @@ virPidFileWritePath;
# util/virpolkit.h +virPolkitAgentCreate; +virPolkitAgentDestroy; virPolkitCheckAuth;
diff --git a/src/util/virpolkit.c b/src/util/virpolkit.c index df707f1..6941d74 100644 --- a/src/util/virpolkit.c +++ b/src/util/virpolkit.c @@ -20,20 +20,22 @@ */
#include <config.h> +#include <poll.h>
#if WITH_POLKIT0 # include <polkit/polkit.h> # include <polkit-dbus/polkit-dbus.h> #endif
-#include "virpolkit.h" #include "vircommand.h" +#include "virpolkit.h" #include "virerror.h" #include "virlog.h" #include "virstring.h" #include "virprocess.h" #include "viralloc.h" #include "virdbus.h" +#include "virfile.h"
#define VIR_FROM_THIS VIR_FROM_POLKIT
@@ -136,6 +138,65 @@ int virPolkitCheckAuth(const char *actionid, }
+/* virPolkitAgentDestroy: + * @cmd: Pointer to the virCommandPtr created during virPolkitAgentCreate + * + * Destroy resources used by Polkit Agent + */ +void +virPolkitAgentDestroy(virCommandPtr cmd) +{ + virCommandFree(cmd); +} + +/* virPolkitAgentCreate: + * + * Allocate and setup a polkit agent + * + * Returns a virCommandPtr on success and NULL on failure + */ +virCommandPtr +virPolkitAgentCreate(void) +{ + virCommandPtr cmd = virCommandNewArgList(PKTTYAGENT, "--process", NULL); + int pipe_fd[2] = {-1, -1}; + struct pollfd pollfd; + int outfd = STDOUT_FILENO; + int errfd = STDERR_FILENO; + + if (!isatty(STDIN_FILENO)) + goto error; + + if (pipe2(pipe_fd, 0) < 0) + goto error; + + virCommandAddArgFormat(cmd, "%lld", (long long int) getpid()); + virCommandAddArg(cmd, "--notify-fd"); + virCommandAddArgFormat(cmd, "%d", pipe_fd[1]); + virCommandAddArg(cmd, "--fallback"); + virCommandSetInputFD(cmd, STDIN_FILENO); + virCommandSetOutputFD(cmd, &outfd); + virCommandSetErrorFD(cmd, &errfd); + virCommandPassFD(cmd, pipe_fd[1], VIR_COMMAND_PASS_FD_CLOSE_PARENT); + if (virCommandRunAsync(cmd, NULL) < 0) + goto error; + + pollfd.fd = pipe_fd[0]; + pollfd.events = POLLHUP; + + if (poll(&pollfd, 1, -1) < 0) + goto error; + + return cmd; + + error: + VIR_FORCE_CLOSE(pipe_fd[0]); + VIR_FORCE_CLOSE(pipe_fd[1]); + virCommandFree(cmd); + return NULL; +} + + #elif WITH_POLKIT0 int virPolkitCheckAuth(const char *actionid, pid_t pid, @@ -254,4 +315,18 @@ int virPolkitCheckAuth(const char *actionid ATTRIBUTE_UNUSED, }
+void +virPolkitAgentDestroy(virCommandPtr cmd ATTRIBUTE_UNUSED) +{ + return; /* do nothing */ +} + + +virCommandPtr +virPolkitAgentCreate(void) +{ + virReportError(VIR_ERR_AUTH_FAILED, "%s", + _("polkit text authentication agent unavailable")); + return NULL; +} #endif /* WITH_POLKIT1 */ diff --git a/src/util/virpolkit.h b/src/util/virpolkit.h index 36122d0..f0aea37 100644 --- a/src/util/virpolkit.h +++ b/src/util/virpolkit.h @@ -24,6 +24,8 @@
# include "internal.h"
Based on Martin's comments - I included "vircommand.h" here
+# define PKTTYAGENT "/usr/bin/pkttyagent" + int virPolkitCheckAuth(const char *actionid, pid_t pid, unsigned long long startTime, @@ -31,4 +33,7 @@ int virPolkitCheckAuth(const char *actionid, const char **details, bool allowInteraction);
+void virPolkitAgentDestroy(virCommandPtr cmd); +virCommandPtr virPolkitAgentCreate(void);
Rather than exposing use of virCommand in the API, I'd suggest you create a
typedef struct virPolkitAgent virPolkitAgent; typedef virPolkitAgent *virPolkitAgentPtr;
okidoke... Funny I had done it this way at some point, but when virCommandPtr was the only thing in the structure, I just opted to use virCommandPtr directly. Anyway, the following is now defined: typedef struct _virPolkitAgent virPolkitAgent; typedef virPolkitAgent *virPolkitAgentPtr; void virPolkitAgentDestroy(virPolkitAgentPtr cmd); virPolkitAgentPtr virPolkitAgentCreate(void);
in the header file here
and in the .c do
struct virPolitAgent { virCommandPtr; };
Inside the "#if WITH_POLKIT1" there is now a : struct _virPolkitAgent { virCommandPtr cmd; }; results in mods to virPolkitAgentDestroy: virPolkitAgentDestroy(virPolkitAgentPtr agent) { if (!agent) return; virCommandFree(agent->cmd); VIR_FREE(agent); } and the VIR_ALLOC(agent) in virPolkitAgentCreate as well as calling virPolkitAgentDestroy(agent) instead of virCommandFree in error:
so we hide use of virCommand
diff --git a/tests/virpolkittest.c b/tests/virpolkittest.c index 73f001b..b46e65f 100644 --- a/tests/virpolkittest.c +++ b/tests/virpolkittest.c @@ -27,6 +27,7 @@ # include <stdlib.h> # include <dbus/dbus.h>
+# include "vircommand.h"
Forgot to note in my response to Martin that virpolkittest.c doesn't need a change here since virpolkit.h now includes vircommand.h. Same of course for virsh.h. Should I post a v4 of patches 2 & 3? I'll still wait for the release to push the patches though. Tks - John

On Thu, Feb 25, 2016 at 11:47:03AM -0500, John Ferlan wrote:
On 02/25/2016 09:25 AM, Daniel P. Berrange wrote:
int virPolkitCheckAuth(const char *actionid, pid_t pid, unsigned long long startTime, @@ -31,4 +33,7 @@ int virPolkitCheckAuth(const char *actionid, const char **details, bool allowInteraction);
+void virPolkitAgentDestroy(virCommandPtr cmd); +virCommandPtr virPolkitAgentCreate(void);
Rather than exposing use of virCommand in the API, I'd suggest you create a
typedef struct virPolkitAgent virPolkitAgent; typedef virPolkitAgent *virPolkitAgentPtr;
okidoke... Funny I had done it this way at some point, but when virCommandPtr was the only thing in the structure, I just opted to use virCommandPtr directly. Anyway, the following is now defined:
It is just nice from the POV of isolating callers from impl detail. It means we can switch to use direct DBus calls in the future without changing any callers.
Forgot to note in my response to Martin that virpolkittest.c doesn't need a change here since virpolkit.h now includes vircommand.h. Same of course for virsh.h.
Should I post a v4 of patches 2 & 3?
Yeah, it'd be good to send v4 Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Introduce virPolkitAgentCreate and virPolkitAgentDestroy virPolkitAgentCreate will run the polkit pkttyagent image as an asynchronous command in order to handle the local agent authentication via stdin/stdout. The code makes use of the pkttyagent --notify-fd mechanism to let it know when the agent is successfully registered. virPolkitAgentDestroy will close the command effectively reaping our child process Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/libvirt_private.syms | 2 ++ src/util/virpolkit.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++- src/util/virpolkit.h | 9 +++++ 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4b40612..4c53bf4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2032,6 +2032,8 @@ virPidFileWritePath; # util/virpolkit.h +virPolkitAgentCreate; +virPolkitAgentDestroy; virPolkitCheckAuth; diff --git a/src/util/virpolkit.c b/src/util/virpolkit.c index df707f1..3bb60a5 100644 --- a/src/util/virpolkit.c +++ b/src/util/virpolkit.c @@ -20,6 +20,7 @@ */ #include <config.h> +#include <poll.h> #if WITH_POLKIT0 # include <polkit/polkit.h> @@ -27,19 +28,24 @@ #endif #include "virpolkit.h" -#include "vircommand.h" #include "virerror.h" #include "virlog.h" #include "virstring.h" #include "virprocess.h" #include "viralloc.h" #include "virdbus.h" +#include "virfile.h" #define VIR_FROM_THIS VIR_FROM_POLKIT VIR_LOG_INIT("util.polkit"); #if WITH_POLKIT1 + +struct _virPolkitAgent { + virCommandPtr cmd; +}; + /* * virPolkitCheckAuth: * @actionid: permission to check @@ -136,6 +142,74 @@ int virPolkitCheckAuth(const char *actionid, } +/* virPolkitAgentDestroy: + * @cmd: Pointer to the virCommandPtr created during virPolkitAgentCreate + * + * Destroy resources used by Polkit Agent + */ +void +virPolkitAgentDestroy(virPolkitAgentPtr agent) +{ + if (!agent) + return; + + virCommandFree(agent->cmd); + VIR_FREE(agent); +} + +/* virPolkitAgentCreate: + * + * Allocate and setup a polkit agent + * + * Returns a virCommandPtr on success and NULL on failure + */ +virPolkitAgentPtr +virPolkitAgentCreate(void) +{ + virPolkitAgentPtr agent; + virCommandPtr cmd = virCommandNewArgList(PKTTYAGENT, "--process", NULL); + int pipe_fd[2] = {-1, -1}; + struct pollfd pollfd; + int outfd = STDOUT_FILENO; + int errfd = STDERR_FILENO; + + if (!isatty(STDIN_FILENO)) + goto error; + + if (pipe2(pipe_fd, 0) < 0) + goto error; + + if (VIR_ALLOC(agent) < 0) + goto error; + agent->cmd = cmd; + + virCommandAddArgFormat(cmd, "%lld", (long long int) getpid()); + virCommandAddArg(cmd, "--notify-fd"); + virCommandAddArgFormat(cmd, "%d", pipe_fd[1]); + virCommandAddArg(cmd, "--fallback"); + virCommandSetInputFD(cmd, STDIN_FILENO); + virCommandSetOutputFD(cmd, &outfd); + virCommandSetErrorFD(cmd, &errfd); + virCommandPassFD(cmd, pipe_fd[1], VIR_COMMAND_PASS_FD_CLOSE_PARENT); + if (virCommandRunAsync(cmd, NULL) < 0) + goto error; + + pollfd.fd = pipe_fd[0]; + pollfd.events = POLLHUP; + + if (poll(&pollfd, 1, -1) < 0) + goto error; + + return agent; + + error: + VIR_FORCE_CLOSE(pipe_fd[0]); + VIR_FORCE_CLOSE(pipe_fd[1]); + virPolkitAgentDestroy(agent); + return NULL; +} + + #elif WITH_POLKIT0 int virPolkitCheckAuth(const char *actionid, pid_t pid, @@ -254,4 +328,18 @@ int virPolkitCheckAuth(const char *actionid ATTRIBUTE_UNUSED, } +void +virPolkitAgentDestroy(virCommandPtr cmd ATTRIBUTE_UNUSED) +{ + return; /* do nothing */ +} + + +virCommandPtr +virPolkitAgentCreate(void) +{ + virReportError(VIR_ERR_AUTH_FAILED, "%s", + _("polkit text authentication agent unavailable")); + return NULL; +} #endif /* WITH_POLKIT1 */ diff --git a/src/util/virpolkit.h b/src/util/virpolkit.h index 36122d0..14ff073 100644 --- a/src/util/virpolkit.h +++ b/src/util/virpolkit.h @@ -23,6 +23,9 @@ # define __VIR_POLKIT_H__ # include "internal.h" +# include "vircommand.h" + +# define PKTTYAGENT "/usr/bin/pkttyagent" int virPolkitCheckAuth(const char *actionid, pid_t pid, @@ -31,4 +34,10 @@ int virPolkitCheckAuth(const char *actionid, const char **details, bool allowInteraction); +typedef struct _virPolkitAgent virPolkitAgent; +typedef virPolkitAgent *virPolkitAgentPtr; + +void virPolkitAgentDestroy(virPolkitAgentPtr cmd); +virPolkitAgentPtr virPolkitAgentCreate(void); + #endif /* __VIR_POLKIT_H__ */ -- 2.5.0

On Thu, Feb 25, 2016 at 12:01:05PM -0500, John Ferlan wrote:
Introduce virPolkitAgentCreate and virPolkitAgentDestroy
virPolkitAgentCreate will run the polkit pkttyagent image as an asynchronous command in order to handle the local agent authentication via stdin/stdout. The code makes use of the pkttyagent --notify-fd mechanism to let it know when the agent is successfully registered.
virPolkitAgentDestroy will close the command effectively reaping our child process
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/libvirt_private.syms | 2 ++ src/util/virpolkit.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++- src/util/virpolkit.h | 9 +++++ 3 files changed, 100 insertions(+), 1 deletion(-)
ACK Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

https://bugzilla.redhat.com/show_bug.cgi?id=872166 When the login session doesn't have an ssh -X type display agent in order for libvirtd to run the polkit session authentication, attempts to run 'virsh -c qemu:///system list' from an unauthorized user (or one that isn't part of the libvirt /etc/group) will fail with the following error from libvirtd: error: authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage' In order to handle the local authentication, we will use the new virPolkitAgentCreate API in order to create a text based authentication agent for our non readonly session to authenticate with. The new code will execute in a loop allowing 5 failures to authenticate before failing out. With this patch in place, the following occurs: $ virsh -c qemu:///system list ==== AUTHENTICATING FOR org.libvirt.unix.manage === System policy prevents management of local virtualized systems Authenticating as: Some User (SUser) Password: ==== AUTHENTICATION COMPLETE === Id Name State ---------------------------------------------------- 1 somedomain running $ Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh.c | 38 ++++++++++++++++++++++++++++++++++---- tools/virsh.h | 2 ++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index b96dbda..9a97140 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -143,6 +143,8 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly) int interval = 5; /* Default */ int count = 6; /* Default */ bool keepalive_forced = false; + virCommandPtr pkagent = NULL; + int authfail = 0; if (ctl->keepalive_interval >= 0) { interval = ctl->keepalive_interval; @@ -153,10 +155,35 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly) keepalive_forced = true; } - c = virConnectOpenAuth(uri, virConnectAuthPtrDefault, - readonly ? VIR_CONNECT_RO : 0); + do { + virErrorPtr err; + + if ((c = virConnectOpenAuth(uri, virConnectAuthPtrDefault, + readonly ? VIR_CONNECT_RO : 0))) + break; + + if (readonly) + goto cleanup; + + err = virGetLastError(); + if (err && err->domain == VIR_FROM_POLKIT && + err->code == VIR_ERR_AUTH_UNAVAILABLE) { + if (!(pkagent = virPolkitAgentCreate())) + goto cleanup; + } else if (err && err->domain == VIR_FROM_POLKIT && + err->code == VIR_ERR_AUTH_FAILED) { + authfail++; + } else { + goto cleanup; + } + virResetLastError(); + /* Failure to authenticate 5 times should be enough. + * No sense prolonging the agony. + */ + } while (authfail < 5); + if (!c) - return NULL; + goto cleanup; if (interval > 0 && virConnectSetKeepAlive(c, interval, count) != 0) { @@ -165,12 +192,15 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly) _("Cannot setup keepalive on connection " "as requested, disconnecting")); virConnectClose(c); - return NULL; + c = NULL; + goto cleanup; } vshDebug(ctl, VSH_ERR_INFO, "%s", _("Failed to setup keepalive on connection\n")); } + cleanup: + virPolkitAgentDestroy(pkagent); return c; } diff --git a/tools/virsh.h b/tools/virsh.h index 8b5e5ba..a6c7289 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -36,6 +36,8 @@ # include "internal.h" # include "virerror.h" # include "virthread.h" +# include "vircommand.h" +# include "virpolkit.h" # include "vsh.h" # define VIRSH_PROMPT_RW "virsh # " -- 2.5.0

On Fri, Feb 12, 2016 at 12:12:33PM -0500, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=872166
When the login session doesn't have an ssh -X type display agent in order for libvirtd to run the polkit session authentication, attempts to run 'virsh -c qemu:///system list' from an unauthorized user (or one that isn't part of the libvirt /etc/group) will fail with the following error from libvirtd:
error: authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage'
In order to handle the local authentication, we will use the new virPolkitAgentCreate API in order to create a text based authentication agent for our non readonly session to authenticate with.
The new code will execute in a loop allowing 5 failures to authenticate before failing out.
With this patch in place, the following occurs:
$ virsh -c qemu:///system list ==== AUTHENTICATING FOR org.libvirt.unix.manage === System policy prevents management of local virtualized systems Authenticating as: Some User (SUser) Password: ==== AUTHENTICATION COMPLETE === Id Name State ---------------------------------------------------- 1 somedomain running
$
Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh.c | 38 ++++++++++++++++++++++++++++++++++---- tools/virsh.h | 2 ++ 2 files changed, 36 insertions(+), 4 deletions(-)
ACK, though it'd need updating based on my comment on #2 Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

https://bugzilla.redhat.com/show_bug.cgi?id=872166 When the login session doesn't have an ssh -X type display agent in order for libvirtd to run the polkit session authentication, attempts to run 'virsh -c qemu:///system list' from an unauthorized user (or one that isn't part of the libvirt /etc/group) will fail with the following error from libvirtd: error: authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage' In order to handle the local authentication, we will use the new virPolkitAgentCreate API in order to create a text based authentication agent for our non readonly session to authenticate with. The new code will execute in a loop allowing 5 failures to authenticate before failing out. With this patch in place, the following occurs: $ virsh -c qemu:///system list ==== AUTHENTICATING FOR org.libvirt.unix.manage === System policy prevents management of local virtualized systems Authenticating as: Some User (SUser) Password: ==== AUTHENTICATION COMPLETE === Id Name State ---------------------------------------------------- 1 somedomain running $ Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh.c | 38 ++++++++++++++++++++++++++++++++++---- tools/virsh.h | 1 + 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index eb84dd0..72446be 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -143,6 +143,8 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly) int interval = 5; /* Default */ int count = 6; /* Default */ bool keepalive_forced = false; + virPolkitAgentPtr pkagent = NULL; + int authfail = 0; if (ctl->keepalive_interval >= 0) { interval = ctl->keepalive_interval; @@ -153,10 +155,35 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly) keepalive_forced = true; } - c = virConnectOpenAuth(uri, virConnectAuthPtrDefault, - readonly ? VIR_CONNECT_RO : 0); + do { + virErrorPtr err; + + if ((c = virConnectOpenAuth(uri, virConnectAuthPtrDefault, + readonly ? VIR_CONNECT_RO : 0))) + break; + + if (readonly) + goto cleanup; + + err = virGetLastError(); + if (err && err->domain == VIR_FROM_POLKIT && + err->code == VIR_ERR_AUTH_UNAVAILABLE) { + if (!(pkagent = virPolkitAgentCreate())) + goto cleanup; + } else if (err && err->domain == VIR_FROM_POLKIT && + err->code == VIR_ERR_AUTH_FAILED) { + authfail++; + } else { + goto cleanup; + } + virResetLastError(); + /* Failure to authenticate 5 times should be enough. + * No sense prolonging the agony. + */ + } while (authfail < 5); + if (!c) - return NULL; + goto cleanup; if (interval > 0 && virConnectSetKeepAlive(c, interval, count) != 0) { @@ -165,12 +192,15 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly) _("Cannot setup keepalive on connection " "as requested, disconnecting")); virConnectClose(c); - return NULL; + c = NULL; + goto cleanup; } vshDebug(ctl, VSH_ERR_INFO, "%s", _("Failed to setup keepalive on connection\n")); } + cleanup: + virPolkitAgentDestroy(pkagent); return c; } diff --git a/tools/virsh.h b/tools/virsh.h index 8b5e5ba..fd552bb 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -36,6 +36,7 @@ # include "internal.h" # include "virerror.h" # include "virthread.h" +# include "virpolkit.h" # include "vsh.h" # define VIRSH_PROMPT_RW "virsh # " -- 2.5.0

On Thu, Feb 25, 2016 at 12:01:59PM -0500, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=872166
When the login session doesn't have an ssh -X type display agent in order for libvirtd to run the polkit session authentication, attempts to run 'virsh -c qemu:///system list' from an unauthorized user (or one that isn't part of the libvirt /etc/group) will fail with the following error from libvirtd:
error: authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage'
In order to handle the local authentication, we will use the new virPolkitAgentCreate API in order to create a text based authentication agent for our non readonly session to authenticate with.
The new code will execute in a loop allowing 5 failures to authenticate before failing out.
With this patch in place, the following occurs:
$ virsh -c qemu:///system list ==== AUTHENTICATING FOR org.libvirt.unix.manage === System policy prevents management of local virtualized systems Authenticating as: Some User (SUser) Password: ==== AUTHENTICATION COMPLETE === Id Name State ---------------------------------------------------- 1 somedomain running
$
Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh.c | 38 ++++++++++++++++++++++++++++++++++---- tools/virsh.h | 1 + 2 files changed, 35 insertions(+), 4 deletions(-)
ACK Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

ping... Thanks, John On 02/12/2016 12:12 PM, John Ferlan wrote:
v2: http://www.redhat.com/archives/libvir-list/2016-February/msg00618.html
Adjustments since v2:
Patch 1 - Change not only the message (as requested), but also use a different and new error code (VIR_ERR_AUTH_UNAVAILABLE).
Patch 2 - Added a check for "if (!isatty(STDIN_FILENO))" Used a new parameter for pkttyagent call - "--notify-fd", which is documented as "To get notified when the authentication agent has been registered either listen to the Changed D-Bus signal or use --notify-fd to pass the number of a file descriptor that has been passed to the program. This file descriptor will then be closed when the authentication agent has been successfully registered. Followed the systemd mechanism. If it's felt that a timeout of -1 is too dangerous, I'd be fine with changing it.
Patch 3 - Since we now can determine our failure based on err->code, use the new VIR_ERR_AUTH_UNAVAILABLE to attempt the AgentCreate. Also, since virPolkitAgentCreate now will wait for the agent to start before returning, the agentstart counter is removed.
John Ferlan (3): polkit: Adjust message when authentication agent isn't found util: Introduce API's for Polkit text authentication virsh: Add support for text based polkit authentication
include/libvirt/virterror.h | 3 +- src/libvirt_private.syms | 2 ++ src/util/virerror.c | 8 ++++- src/util/virpolkit.c | 85 ++++++++++++++++++++++++++++++++++++++++++--- src/util/virpolkit.h | 5 +++ tests/virpolkittest.c | 8 +++-- tools/virsh.c | 38 +++++++++++++++++--- tools/virsh.h | 2 ++ 8 files changed, 138 insertions(+), 13 deletions(-)
participants (3)
-
Daniel P. Berrange
-
John Ferlan
-
Martin Kletzander