From: "Daniel P. Berrange" <berra...@redhat.com>

---
 po/POTFILES.in                       |    1 +
 src/Makefile.am                      |   12 ++-
 src/access/org.libvirt.domain.policy |   37 ++++++++
 src/access/viraccessdriverpolkit.c   |  163 ++++++++++++++++++++++++++++++++++
 src/access/viraccessdriverpolkit.h   |   28 ++++++
 src/access/viraccessmanager.c        |    2 +
 6 files changed, 241 insertions(+), 2 deletions(-)
 create mode 100644 src/access/org.libvirt.domain.policy
 create mode 100644 src/access/viraccessdriverpolkit.c
 create mode 100644 src/access/viraccessdriverpolkit.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0a5443f..0548479 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,6 +4,7 @@ daemon/remote.c
 daemon/remote_dispatch.h
 daemon/stream.c
 gnulib/lib/gai_strerror.c
+src/access/viraccessdriverpolkit.c
 src/access/viraccessmanager.c
 src/conf/cpu_conf.c
 src/conf/domain_conf.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 0baa17d..ebc8301 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -523,7 +523,12 @@ ACCESS_DRIVER_SOURCES = \
                access/viraccessmanager.h access/viraccessmanager.c \
                access/viraccessdriver.h \
                access/viraccessdrivernop.h access/viraccessdrivernop.c \
-               access/viraccessdriverstack.h access/viraccessdriverstack.c
+               access/viraccessdriverstack.h access/viraccessdriverstack.c \
+               access/viraccessdriverpolkit.h access/viraccessdriverpolkit.c
+
+ACCESS_DRIVER_POLKIT_POLICY = \
+               access/org.libvirt.domain.policy
+
 
 NODE_DEVICE_DRIVER_SOURCES =                                   \
                node_device/node_device_driver.c \
@@ -1116,6 +1121,8 @@ libvirt_driver_access_la_CFLAGS = \
 libvirt_driver_access_la_LDFLAGS = $(AM_LDFLAGS)
 libvirt_driver_access_la_LIBADD =
 
+polkitactiondir = $(datadir)/polkit-1/actions
+polkitaction_DATA = $(ACCESS_DRIVER_POLKIT_POLICY)
 
 # Add all conditional sources just in case...
 EXTRA_DIST +=                                                  \
@@ -1152,7 +1159,8 @@ EXTRA_DIST +=                                             
        \
                $(SECRET_DRIVER_SOURCES)                        \
                $(VBOX_DRIVER_EXTRA_DIST)                       \
                $(VMWARE_DRIVER_SOURCES)                        \
-               $(XENXS_SOURCES)
+               $(XENXS_SOURCES)                                \
+               $(ACCESS_DRIVER_POLKIT_POLICY)
 
 check-local: augeas-check
 
diff --git a/src/access/org.libvirt.domain.policy 
b/src/access/org.libvirt.domain.policy
new file mode 100644
index 0000000..a8ebd84
--- /dev/null
+++ b/src/access/org.libvirt.domain.policy
@@ -0,0 +1,37 @@
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd";>
+
+<!--
+Policy definitions for libvirt daemon
+
+Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
+
+libvirt is licensed to you under the GNU Lesser General Public License
+version 2. See COPYING for details.
+
+NOTE: If you make changes to this file, make sure to validate the file
+using the polkit-policy-file-validate(1) tool. Changes made to this
+file are instantly applied.
+-->
+
+<policyconfig>
+    <action id="org.libvirt.domain.getattr">
+      <description>Get virtual domain attributes</description>
+      <message>System policy prevents getattr on guest domains</message>
+      <defaults>
+        <allow_any>yes</allow_any>
+        <allow_inactive>yes</allow_inactive>
+        <allow_active>yes</allow_active>
+      </defaults>
+    </action>
+    <action id="org.libvirt.domain.read">
+      <description>Get virtual domain attributes</description>
+      <message>System policy prevents getattr on guest domains</message>
+      <defaults>
+        <allow_any>yes</allow_any>
+        <allow_inactive>yes</allow_inactive>
+        <allow_active>yes</allow_active>
+      </defaults>
+    </action>
+</policyconfig>
diff --git a/src/access/viraccessdriverpolkit.c 
b/src/access/viraccessdriverpolkit.c
new file mode 100644
index 0000000..d330653
--- /dev/null
+++ b/src/access/viraccessdriverpolkit.c
@@ -0,0 +1,163 @@
+/*
+ * viraccessdriverpolkit.c: polkited access control driver
+ *
+ * Copyright (C) 2012 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#include <config.h>
+
+#include "access/viraccessdriverpolkit.h"
+#include "memory.h"
+#include "command.h"
+#include "logging.h"
+#include "virterror_internal.h"
+
+#define VIR_FROM_THIS VIR_FROM_ACCESS
+#define virAccessError(code, ...)                                       \
+    virReportErrorHelper(VIR_FROM_THIS, code, __FILE__,                 \
+                         __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define VIR_ACCESS_DRIVER_POLKIT_ACTION_PREFIX "org.libvirt"
+
+typedef struct _virAccessDriverPolkitPrivate virAccessDriverPolkitPrivate;
+typedef virAccessDriverPolkitPrivate *virAccessDriverPolkitPrivatePtr;
+
+struct _virAccessDriverPolkitPrivate {
+    bool ignore;
+};
+
+
+static void virAccessDriverPolkitCleanup(virAccessManagerPtr manager 
ATTRIBUTE_UNUSED)
+{
+}
+
+
+static char *
+virAccessDriverPolkitFormatAction(const char *typename,
+                                  const char *avname)
+{
+    char *actionid = NULL;
+
+    if (virAsprintf(&actionid, "%s.%s.%s",
+                    VIR_ACCESS_DRIVER_POLKIT_ACTION_PREFIX,
+                    typename, avname) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    return actionid;
+}
+
+
+static char *
+virAccessDriverPolkitFormatProcess(void)
+{
+    virIdentityPtr identity = virAccessManagerGetEffectiveIdentity();
+    const char *process = NULL;
+    char *ret = NULL;
+
+    if (!identity) {
+        virAccessError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("No identity available"));
+        return NULL;
+    }
+    if (virIdentityGetAttr(identity, VIR_IDENTITY_ATTR_UNIX_PROCESS_ID, 
&process) < 0)
+        goto cleanup;
+
+    if (!process) {
+        virAccessError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("No UNIX process ID available"));
+        goto cleanup;
+    }
+
+    if (!(ret = strdup(process))) {
+        virReportOOMError();
+        goto cleanup;
+    }
+cleanup:
+    virIdentityFree(identity);
+    return ret;
+}
+
+
+static bool
+virAccessDriverPolkitCheck(virAccessManagerPtr manager ATTRIBUTE_UNUSED,
+                           const char *typename,
+                           const char *avname)
+{
+    char *actionid = virAccessDriverPolkitFormatAction(typename, avname);
+    char *process = virAccessDriverPolkitFormatProcess();
+    virCommandPtr cmd;
+    int status;
+    int ret = false;
+
+    if (!actionid || !process)
+        goto cleanup;
+
+    cmd = virCommandNewArgList(PKCHECK_PATH,
+                               "--action-id", actionid,
+                               "--process", process,
+                               NULL);
+
+    if (virCommandRun(cmd, &status) < 0)
+        goto cleanup;
+
+    if (status != 0) {
+        char *tmp = virCommandTranslateStatus(status);
+        virAccessError(VIR_ERR_ACCESS_DENIED,
+                       _("Policy kit denied action %s from %s: %s"),
+                       actionid, process, NULLSTR(tmp));
+        VIR_FREE(tmp);
+        goto cleanup;
+    }
+
+    ret = true;
+
+cleanup:
+    VIR_FREE(actionid);
+    VIR_FREE(process);
+    return ret;
+}
+
+
+static bool
+virAccessDriverPolkitCheckConnect(virAccessManagerPtr manager,
+                                  virAccessVectorConnect av)
+{
+    return virAccessDriverPolkitCheck(manager,
+                                      "connect",
+                                      virAccessVectorConnectTypeToString(av));
+}
+
+
+static bool
+virAccessDriverPolkitCheckDomain(virAccessManagerPtr manager,
+                                 virDomainDefPtr def ATTRIBUTE_UNUSED,
+                                 virAccessVectorDomain av)
+{
+    return virAccessDriverPolkitCheck(manager,
+                                      "domain",
+                                      virAccessVectorDomainTypeToString(av));
+}
+
+
+virAccessDriver accessDriverPolkit = {
+    .name = "polkit",
+    .cleanup = virAccessDriverPolkitCleanup,
+    .checkConnect = virAccessDriverPolkitCheckConnect,
+    .checkDomain = virAccessDriverPolkitCheckDomain,
+};
diff --git a/src/access/viraccessdriverpolkit.h 
b/src/access/viraccessdriverpolkit.h
new file mode 100644
index 0000000..ac71fa5
--- /dev/null
+++ b/src/access/viraccessdriverpolkit.h
@@ -0,0 +1,28 @@
+/*
+ * viraccessdriverpolkit.h: polkited access control driver
+ *
+ * Copyright (C) 2012 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#ifndef __VIR_ACCESS_DRIVER_POLKIT_H__
+# define __VIR_ACCESS_DRIVER_POLKIT_H__
+
+# include "access/viraccessdriver.h"
+
+extern virAccessDriver accessDriverPolkit;
+
+#endif /* __VIR_ACCESS_DRIVER_POLKIT_H__ */
diff --git a/src/access/viraccessmanager.c b/src/access/viraccessmanager.c
index 5bb4404..4698a4f 100644
--- a/src/access/viraccessmanager.c
+++ b/src/access/viraccessmanager.c
@@ -29,6 +29,7 @@
 #endif
 #include "access/viraccessdrivernop.h"
 #include "access/viraccessdriverstack.h"
+#include "access/viraccessdriverpolkit.h"
 #include "logging.h"
 
 #define VIR_FROM_THIS VIR_FROM_ACCESS
@@ -206,6 +207,7 @@ static virAccessManagerPtr 
virAccessManagerNewDriver(virAccessDriverPtr drv)
 
 static virAccessDriverPtr accessDrivers[] = {
     &accessDriverNop,
+    &accessDriverPolkit,
 };
 
 
-- 
1.7.7.5

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to