[PATCH 3/3] virsh: Add support for text based polkit authentication

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

 



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 failed: no agent is available to authenticate -
       polkit agent 'org.libvirt.unix.manage' is not available

In order to handle the local authentication, add a new switch "--pkauth"
to virsh which will make use of the virPolkitAgent* API's in order to
handle the text authentication when not a readonly request.

With this patch in place, the following occurs:

$ virsh --pkauth -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@xxxxxxxxxx>
---
 tools/virsh.c   | 22 +++++++++++++++++++---
 tools/virsh.h   |  2 ++
 tools/virsh.pod | 10 ++++++++++
 tools/vsh.h     |  1 +
 4 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index b96dbda..83cebe0 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -143,6 +143,7 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly)
     int interval = 5; /* Default */
     int count = 6;    /* Default */
     bool keepalive_forced = false;
+    virCommandPtr pkagent = NULL;
 
     if (ctl->keepalive_interval >= 0) {
         interval = ctl->keepalive_interval;
@@ -153,10 +154,17 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly)
         keepalive_forced = true;
     }
 
+    if (!readonly && ctl->pkauth) {
+        if (!(pkagent = virPolkitAgentCreate()))
+            return NULL;
+        if (virPolkitAgentCheck() < 0)
+            goto cleanup;
+    }
+
     c = virConnectOpenAuth(uri, virConnectAuthPtrDefault,
                            readonly ? VIR_CONNECT_RO : 0);
     if (!c)
-        return NULL;
+        goto cleanup;
 
     if (interval > 0 &&
         virConnectSetKeepAlive(c, interval, count) != 0) {
@@ -165,12 +173,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;
 }
 
@@ -490,6 +501,7 @@ virshUsage(void)
                       "    -K | --keepalive-count=NUM\n"
                       "                            number of possible missed keepalive messages\n"
                       "    -l | --log=FILE         output logging to file\n"
+                      "    -p | --pkauth           start background polkit text authentication agent\n"
                       "    -q | --quiet            quiet mode\n"
                       "    -r | --readonly         connect readonly\n"
                       "    -t | --timing           print timing information\n"
@@ -701,13 +713,14 @@ virshParseArgv(vshControl *ctl, int argc, char **argv)
         {"readonly", no_argument, NULL, 'r'},
         {"timing", no_argument, NULL, 't'},
         {"version", optional_argument, NULL, 'v'},
+        {"pkauth", no_argument, NULL, 'p'},
         {NULL, 0, NULL, 0}
     };
 
     /* Standard (non-command) options. The leading + ensures that no
      * argument reordering takes place, so that command options are
      * not confused with top-level virsh options. */
-    while ((arg = getopt_long(argc, argv, "+:c:d:e:hk:K:l:qrtvV", opt, &longindex)) != -1) {
+    while ((arg = getopt_long(argc, argv, "+:c:d:e:hk:K:l:pqrtvV", opt, &longindex)) != -1) {
         switch (arg) {
         case 'c':
             VIR_FREE(ctl->connname);
@@ -779,6 +792,9 @@ virshParseArgv(vshControl *ctl, int argc, char **argv)
             ctl->logfile = vshStrdup(ctl, optarg);
             vshOpenLogFile(ctl);
             break;
+        case 'p':
+            ctl->pkauth = true;
+            break;
         case 'q':
             ctl->quiet = true;
             break;
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 # "
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 435c649..5368de7 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -90,6 +90,16 @@ no effect to this setting in case the I<INTERVAL> is set to 0.
 
 Output logging details to I<FILE>.
 
+=item B<-p>, B<--pkauth>
+
+Start a local Polkit Authentication Agent in order to authenticate an
+unprivileged user for write access from a text session that cannot
+autolaunch a graphical Polkit Agent. Using this mechanism is an
+alternative to adding the user to the libvirt group list in /etc/group.
+The authentication processing requires the ability to view stdout and
+read from stdin. If Polkit is not available on the host, then the
+command will fail.
+
 =item B<-q>, B<--quiet>
 
 Avoid extra informational messages.
diff --git a/tools/vsh.h b/tools/vsh.h
index 0c5abdc..151fdcc 100644
--- a/tools/vsh.h
+++ b/tools/vsh.h
@@ -202,6 +202,7 @@ struct _vshControl {
     vshCmd *cmd;                /* the current command */
     char *cmdstr;               /* string with command */
     bool imode;                 /* interactive mode? */
+    bool pkauth;                /* start polkit authentication agent */
     bool quiet;                 /* quiet mode */
     bool timing;                /* print timing info? */
     int debug;                  /* print debug messages? */
-- 
2.5.0

--
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]