[libvirt] [PATCH 07/12] Add a policy kit access control driver

Daniel P. Berrange berrange at redhat.com
Wed May 2 11:44:14 UTC 2012


From: "Daniel P. Berrange" <berrange at 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 f898887..0c18fa0 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -6,6 +6,7 @@ daemon/remote_dispatch.h
 daemon/stream.c
 gnulib/lib/gai_strerror.c
 gnulib/lib/regcomp.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 0293562..f9972ac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -536,7 +536,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 \
@@ -1130,6 +1135,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 +=							\
@@ -1166,7 +1173,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..8364986
--- /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,
+                                  virAccessPermConnect av)
+{
+    return virAccessDriverPolkitCheck(manager,
+                                      "connect",
+                                      virAccessPermConnectTypeToString(av));
+}
+
+
+static bool
+virAccessDriverPolkitCheckDomain(virAccessManagerPtr manager,
+                                 virDomainDefPtr def ATTRIBUTE_UNUSED,
+                                 virAccessPermDomain av)
+{
+    return virAccessDriverPolkitCheck(manager,
+                                      "domain",
+                                      virAccessPermDomainTypeToString(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 4e77bd6..e7444d5 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
@@ -216,6 +217,7 @@ static virAccessManagerPtr virAccessManagerNewDriver(virAccessDriverPtr drv)
 
 static virAccessDriverPtr accessDrivers[] = {
     &accessDriverNop,
+    &accessDriverPolkit,
 };
 
 
-- 
1.7.10




More information about the libvir-list mailing list