|
|
7a3408 |
From 80ea7f1e17cc676c591988de47396dd24d390631 Mon Sep 17 00:00:00 2001
|
|
|
7a3408 |
Message-Id: <80ea7f1e17cc676c591988de47396dd24d390631@dist-git>
|
|
|
7a3408 |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
Date: Tue, 4 Aug 2015 14:05:52 +0200
|
|
|
7a3408 |
Subject: [PATCH] examples: Add example polkit ACL rules
|
|
|
7a3408 |
|
|
|
7a3408 |
Creating ACL rules is not exactly easy and existing examples are pretty
|
|
|
7a3408 |
simple. This patch adds a somewhat complex example which defines several
|
|
|
7a3408 |
roles. Admins can do everything, operators can do basic operations
|
|
|
7a3408 |
on any domain and several groups of users who act as operators but only
|
|
|
7a3408 |
on a limited set of domains.
|
|
|
7a3408 |
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
(cherry picked from commit 29b5167417483ef80f6c3fce12811b59a1e2bd55)
|
|
|
7a3408 |
|
|
|
7a3408 |
https://bugzilla.redhat.com/show_bug.cgi?id=1115289
|
|
|
7a3408 |
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
---
|
|
|
7a3408 |
Makefile.am | 2 +-
|
|
|
7a3408 |
configure.ac | 1 +
|
|
|
7a3408 |
docs/aclpolkit.html.in | 6 ++
|
|
|
7a3408 |
examples/polkit/Makefile.am | 17 +++++
|
|
|
7a3408 |
examples/polkit/libvirt-acl.rules | 130 ++++++++++++++++++++++++++++++++++++++
|
|
|
7a3408 |
libvirt.spec.in | 3 +
|
|
|
7a3408 |
6 files changed, 158 insertions(+), 1 deletion(-)
|
|
|
7a3408 |
create mode 100644 examples/polkit/Makefile.am
|
|
|
7a3408 |
create mode 100644 examples/polkit/libvirt-acl.rules
|
|
|
7a3408 |
|
|
|
7a3408 |
diff --git a/Makefile.am b/Makefile.am
|
|
|
7a3408 |
index 91b943b..d338d5a 100644
|
|
|
7a3408 |
--- a/Makefile.am
|
|
|
7a3408 |
+++ b/Makefile.am
|
|
|
7a3408 |
@@ -23,7 +23,7 @@ SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \
|
|
|
7a3408 |
tests po examples/object-events examples/hellolibvirt \
|
|
|
7a3408 |
examples/dominfo examples/domsuspend examples/apparmor \
|
|
|
7a3408 |
examples/xml/nwfilter examples/openauth examples/systemtap \
|
|
|
7a3408 |
- tools/wireshark examples/dommigrate \
|
|
|
7a3408 |
+ tools/wireshark examples/dommigrate examples/polkit \
|
|
|
7a3408 |
examples/lxcconvert examples/domtop
|
|
|
7a3408 |
|
|
|
7a3408 |
ACLOCAL_AMFLAGS = -I m4
|
|
|
7a3408 |
diff --git a/configure.ac b/configure.ac
|
|
|
7a3408 |
index f3ae6ca..b28d990 100644
|
|
|
7a3408 |
--- a/configure.ac
|
|
|
7a3408 |
+++ b/configure.ac
|
|
|
7a3408 |
@@ -2811,6 +2811,7 @@ AC_CONFIG_FILES([\
|
|
|
7a3408 |
examples/systemtap/Makefile \
|
|
|
7a3408 |
examples/xml/nwfilter/Makefile \
|
|
|
7a3408 |
examples/lxcconvert/Makefile \
|
|
|
7a3408 |
+ examples/polkit/Makefile \
|
|
|
7a3408 |
tools/wireshark/Makefile \
|
|
|
7a3408 |
tools/wireshark/src/Makefile])
|
|
|
7a3408 |
AC_OUTPUT
|
|
|
7a3408 |
diff --git a/docs/aclpolkit.html.in b/docs/aclpolkit.html.in
|
|
|
7a3408 |
index e5a9b16..dae0814 100644
|
|
|
7a3408 |
--- a/docs/aclpolkit.html.in
|
|
|
7a3408 |
+++ b/docs/aclpolkit.html.in
|
|
|
7a3408 |
@@ -348,6 +348,12 @@
|
|
|
7a3408 |
lookup method.
|
|
|
7a3408 |
|
|
|
7a3408 |
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ See
|
|
|
7a3408 |
+ source code
|
|
|
7a3408 |
+ for a more complex example.
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+
|
|
|
7a3408 |
|
|
|
7a3408 |
|
|
|
7a3408 |
|
|
|
7a3408 |
diff --git a/examples/polkit/Makefile.am b/examples/polkit/Makefile.am
|
|
|
7a3408 |
new file mode 100644
|
|
|
7a3408 |
index 0000000..4d213e8
|
|
|
7a3408 |
--- /dev/null
|
|
|
7a3408 |
+++ b/examples/polkit/Makefile.am
|
|
|
7a3408 |
@@ -0,0 +1,17 @@
|
|
|
7a3408 |
+## Copyright (C) 2015 Red Hat, Inc.
|
|
|
7a3408 |
+##
|
|
|
7a3408 |
+## This library is free software; you can redistribute it and/or
|
|
|
7a3408 |
+## modify it under the terms of the GNU Lesser General Public
|
|
|
7a3408 |
+## License as published by the Free Software Foundation; either
|
|
|
7a3408 |
+## version 2.1 of the License, or (at your option) any later version.
|
|
|
7a3408 |
+##
|
|
|
7a3408 |
+## This library is distributed in the hope that it will be useful,
|
|
|
7a3408 |
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
7a3408 |
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
7a3408 |
+## Lesser General Public License for more details.
|
|
|
7a3408 |
+##
|
|
|
7a3408 |
+## You should have received a copy of the GNU Lesser General Public
|
|
|
7a3408 |
+## License along with this library. If not, see
|
|
|
7a3408 |
+## <http://www.gnu.org/licenses/>.
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+EXTRA_DIST = libvirt-acl.rules
|
|
|
7a3408 |
diff --git a/examples/polkit/libvirt-acl.rules b/examples/polkit/libvirt-acl.rules
|
|
|
7a3408 |
new file mode 100644
|
|
|
7a3408 |
index 0000000..dd68365
|
|
|
7a3408 |
--- /dev/null
|
|
|
7a3408 |
+++ b/examples/polkit/libvirt-acl.rules
|
|
|
7a3408 |
@@ -0,0 +1,130 @@
|
|
|
7a3408 |
+/*
|
|
|
7a3408 |
+ * This example defines two groups of roles any user/group can be assigned to.
|
|
|
7a3408 |
+ * An "admin" role which grants full access to all APIs on all objects to its
|
|
|
7a3408 |
+ * members, and other roles which allows their members to all APIs defined in
|
|
|
7a3408 |
+ * restrictedActions on domains matching a regular expressions assigned to
|
|
|
7a3408 |
+ * each role. (Jump below the Role class definition to see them.) Users who
|
|
|
7a3408 |
+ * belong to an "operator" role can act on any domain (matching ".*" RE),
|
|
|
7a3408 |
+ * while members of "userA", "userB", and "userC" roles are limited by more
|
|
|
7a3408 |
+ * specific REs.
|
|
|
7a3408 |
+ *
|
|
|
7a3408 |
+ * A virtualization host admin would define domains with names prefixed by
|
|
|
7a3408 |
+ * customer names and create a separate role for each customer restricting
|
|
|
7a3408 |
+ * its members to manage only domains with the corresponding prefix.
|
|
|
7a3408 |
+ */
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+function Role(name) {
|
|
|
7a3408 |
+ this.name = name;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ this.users = [];
|
|
|
7a3408 |
+ this.groups = [];
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ this.check = function(subject, api, domain) {
|
|
|
7a3408 |
+ var validUser = false
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (this.users.indexOf(subject.user) >= 0) {
|
|
|
7a3408 |
+ validUser = true;
|
|
|
7a3408 |
+ } else {
|
|
|
7a3408 |
+ for (var i = 0; i < subject.groups.length; i++) {
|
|
|
7a3408 |
+ if (this.groups.indexOf(subject.groups[i]) >= 0) {
|
|
|
7a3408 |
+ validUser = true;
|
|
|
7a3408 |
+ break;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (validUser &&
|
|
|
7a3408 |
+ (this.name == "admin" ||
|
|
|
7a3408 |
+ !domain ||
|
|
|
7a3408 |
+ (this.domains && domain.match(this.domains)))) {
|
|
|
7a3408 |
+ var msg = "Access granted: " +
|
|
|
7a3408 |
+ "user = " + subject.user +
|
|
|
7a3408 |
+ ", groups = [" + subject.groups + "]" +
|
|
|
7a3408 |
+ ", role = " + this.name +
|
|
|
7a3408 |
+ ", api = " + api;
|
|
|
7a3408 |
+ if (domain)
|
|
|
7a3408 |
+ msg += ", domain = " + domain;
|
|
|
7a3408 |
+ polkit.log(msg);
|
|
|
7a3408 |
+ return true
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ return false;
|
|
|
7a3408 |
+ };
|
|
|
7a3408 |
+}
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+/* Basic operations and monitoring on a limited set of domains. */
|
|
|
7a3408 |
+var userA = new Role("userA");
|
|
|
7a3408 |
+userA.domains = /^a/;
|
|
|
7a3408 |
+userA.users = ["userA1", "userA2", "userA3", "multiUser"];
|
|
|
7a3408 |
+userA.groups = ["groupA1", "groupA2"];
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+var userB = new Role("userB");
|
|
|
7a3408 |
+userB.domains = /^b/;
|
|
|
7a3408 |
+userB.users = ["userB1", "userB2", "userB3", "multiUser"];
|
|
|
7a3408 |
+userB.groups = ["groupB1", "groupB2", "multiGroup"];
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+var userC = new Role("userC");
|
|
|
7a3408 |
+userC.domains = /^c/;
|
|
|
7a3408 |
+userC.users = ["userC1", "userC2", "userC3"];
|
|
|
7a3408 |
+userC.groups = ["groupC1", "groupC2", "multiGroup"];
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+/* Same as users but on any domain. */
|
|
|
7a3408 |
+var operator = new Role("operator");
|
|
|
7a3408 |
+operator.domains = /.*/;
|
|
|
7a3408 |
+operator.users = ["powerUser1", "powerUser2"];
|
|
|
7a3408 |
+operator.groups = ["powerGroup1", "powerGroup2", "powerGroup3"];
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+var users = [operator, userA, userB, userC];
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+/* Full access. */
|
|
|
7a3408 |
+var admin = new Role("admin");
|
|
|
7a3408 |
+admin.users = ["adminUser1"];
|
|
|
7a3408 |
+admin.groups = ["adminGroup1"];
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+restrictedActions = [
|
|
|
7a3408 |
+ "domain.core-dump",
|
|
|
7a3408 |
+ "domain.fs-freeze",
|
|
|
7a3408 |
+ "domain.fs-trim",
|
|
|
7a3408 |
+ "domain.getattr",
|
|
|
7a3408 |
+ "domain.hibernate",
|
|
|
7a3408 |
+ "domain.init-control",
|
|
|
7a3408 |
+ "domain.inject-nmi",
|
|
|
7a3408 |
+ "domain.open-device",
|
|
|
7a3408 |
+ "domain.open-graphics",
|
|
|
7a3408 |
+ "domain.pm-control",
|
|
|
7a3408 |
+ "domain.read",
|
|
|
7a3408 |
+ "domain.reset",
|
|
|
7a3408 |
+ "domain.save",
|
|
|
7a3408 |
+ "domain.screenshot",
|
|
|
7a3408 |
+ "domain.send-input",
|
|
|
7a3408 |
+ "domain.send-signal",
|
|
|
7a3408 |
+ "domain.set-password",
|
|
|
7a3408 |
+ "domain.set-time",
|
|
|
7a3408 |
+ "domain.snapshot",
|
|
|
7a3408 |
+ "domain.start",
|
|
|
7a3408 |
+ "domain.stop",
|
|
|
7a3408 |
+ "domain.suspend"
|
|
|
7a3408 |
+];
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+polkit.addRule(function(action, subject) {
|
|
|
7a3408 |
+ if (action.id.indexOf("org.libvirt.api.") != 0)
|
|
|
7a3408 |
+ return polkit.Result.NOT_HANDLED;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ var api = action.id.replace("org.libvirt.api.", "");
|
|
|
7a3408 |
+ var domain = action.lookup("domain_name");
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (admin.check(subject, api, domain))
|
|
|
7a3408 |
+ return polkit.Result.YES;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (restrictedActions.indexOf(api) < 0)
|
|
|
7a3408 |
+ return polkit.Result.NOT_HANDLED;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ for (var i = 0; i < users.length; i++) {
|
|
|
7a3408 |
+ if (users[i].check(subject, api, domain))
|
|
|
7a3408 |
+ return polkit.Result.YES;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ return polkit.Result.NO;
|
|
|
7a3408 |
+});
|