Creating ACL rules is not exactly easy and existing examples are pretty simple. This patch adds a somewhat complex example which defines three roles (user, operator, admin) with different permissions. Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- Makefile.am | 2 +- configure.ac | 1 + examples/polkit/Makefile.am | 17 ++++++ examples/polkit/libvirt-acl.rules | 124 ++++++++++++++++++++++++++++++++++++++ libvirt.spec.in | 3 + 5 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 examples/polkit/Makefile.am create mode 100644 examples/polkit/libvirt-acl.rules diff --git a/Makefile.am b/Makefile.am index 91b943b..d338d5a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,7 @@ SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \ tests po examples/object-events examples/hellolibvirt \ examples/dominfo examples/domsuspend examples/apparmor \ examples/xml/nwfilter examples/openauth examples/systemtap \ - tools/wireshark examples/dommigrate \ + tools/wireshark examples/dommigrate examples/polkit \ examples/lxcconvert examples/domtop ACLOCAL_AMFLAGS = -I m4 diff --git a/configure.ac b/configure.ac index 46c80ce..d506c28 100644 --- a/configure.ac +++ b/configure.ac @@ -2805,6 +2805,7 @@ AC_CONFIG_FILES([\ examples/systemtap/Makefile \ examples/xml/nwfilter/Makefile \ examples/lxcconvert/Makefile \ + examples/polkit/Makefile \ tools/wireshark/Makefile \ tools/wireshark/src/Makefile]) AC_OUTPUT diff --git a/examples/polkit/Makefile.am b/examples/polkit/Makefile.am new file mode 100644 index 0000000..4d213e8 --- /dev/null +++ b/examples/polkit/Makefile.am @@ -0,0 +1,17 @@ +## Copyright (C) 2015 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, see +## <http://www.gnu.org/licenses/>. + +EXTRA_DIST = libvirt-acl.rules diff --git a/examples/polkit/libvirt-acl.rules b/examples/polkit/libvirt-acl.rules new file mode 100644 index 0000000..6a93206 --- /dev/null +++ b/examples/polkit/libvirt-acl.rules @@ -0,0 +1,124 @@ +function Role(name) { + this.name = name; + + this.actions = []; + this.users = []; + this.groups = []; + + this.lookup = function(subject) { + if (this.users.indexOf(subject.user) >= 0) + return true; + + for (var i = 0; i < subject.groups.length; i++) { + if (this.groups.indexOf(subject.groups[i]) >= 0) + return true; + } + + return false; + }; + + this.lookupAction = function(action) { + action = action.id.replace("org.libvirt.api.", ""); + if (this.actions.indexOf(action) >= 0) + return true; + else + return false; + }; +} + + +/* Basic operations and monitoring. */ +var user = new Role("user"); +user.users = ["user1", "user2", "user3"]; +user.groups = ["group1", "group2"]; + +/* Same as users plus some privileged operations. */ +var operator = new Role("operator"); +operator.users = ["powerUser1", "powerUser2"]; +operator.groups = ["powerGroup1", "powerGroup2", "powerGroup3"]; + +/* Full access. */ +var admin = new Role("admin"); +admin.users = ["adminUser1"]; +admin.groups = ["adminGroup1"]; + + +user.actions = [ + "domain.core-dump", + "domain.fs-freeze", + "domain.fs-trim", + "domain.getattr", + "domain.hibernate", + "domain.init-control", + "domain.inject-nmi", + "domain.open-device", + "domain.open-graphics", + "domain.pm-control", + "domain.read", + "domain.reset", + "domain.save", + "domain.screenshot", + "domain.send-input", + "domain.send-signal", + "domain.set-password", + "domain.set-time", + "domain.snapshot", + "domain.start", + "domain.stop", + "domain.suspend" +]; +operator.actions = [ + "domain.delete", + "domain.migrate", + "domain.read-secure", + "domain.write", + "network.delete", + "network.getattr", + "network.read", + "network.save", + "network.start", + "network.stop", + "network.write", + "nwfilter.delete", + "nwfilter.getattr", + "nwfilter.read", + "nwfilter.save", + "nwfilter.write", + "secret.delete", + "secret.getattr", + "secret.read", + "secret.read-secure", + "secret.save", + "secret.write", + "storage-pool.refresh", + "storage-vol.create", + "storage-vol.data-read", + "storage-vol.data-write", + "storage-vol.delete", + "storage-vol.format", + "storage-vol.getattr", + "storage-vol.read", + "storage-vol.resize" +]; + +polkit.addRule(function(action, subject) { + if (action.id.indexOf("org.libvirt.api.") != 0) + return polkit.Result.NOT_HANDLED; + + if (admin.lookup(subject)) + return polkit.Result.YES; + + if (operator.lookupAction(action)) { + if (operator.lookup(subject)) + return polkit.Result.YES; + else + return polkit.Result.NO; + } else if (user.lookupAction(action)) { + if (operator.lookup(subject) || user.lookup(subject)) + return polkit.Result.YES; + else + return polkit.Result.NO; + } else { + return polkit.Result.NOT_HANDLED; + } +}); diff --git a/libvirt.spec.in b/libvirt.spec.in index 9a6139a..845efd2 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -2039,6 +2039,9 @@ exit 0 %endif # ! %{with_driver_modules} %if %{with_network} + +%doc examples/polkit/*.rules + %files daemon-config-network %defattr(-, root, root) %dir %{_datadir}/libvirt/networks/ -- 2.5.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list