On Fri, Sep 04, 2015 at 02:19:09PM +0200, Jiri Denemark wrote: > Creating ACL rules is not exactly easy and existing examples are pretty > simple. This patch adds a somewhat complex example which defines several > roles. Admins can do everything, operators can do basic operations > on any domain and several groups of users who act as operators but only > on a limited set of domains. > > Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> > --- > Makefile.am | 2 +- > configure.ac | 1 + > examples/polkit/Makefile.am | 17 ++++++ > examples/polkit/libvirt-acl.rules | 115 ++++++++++++++++++++++++++++++++++++++ > libvirt.spec.in | 3 + > 5 files changed, 137 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 8471a46..136c2e7 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -2809,6 +2809,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..5c26593 > --- /dev/null > +++ b/examples/polkit/libvirt-acl.rules > @@ -0,0 +1,115 @@ It would be beneficial to put some docs in this file header here to explain to people what this example is achieving. > +function Role(name) { > + this.name = name; > + > + this.users = []; > + this.groups = []; > + > + this.check = function(subject, api, domain) { > + var validUser = false > + > + if (this.users.indexOf(subject.user) >= 0) { > + validUser = true; > + } else { > + for (var i = 0; i < subject.groups.length; i++) { > + if (this.groups.indexOf(subject.groups[i]) >= 0) { > + validUser = true; > + break; > + } > + } > + } > + > + if (validUser && > + (this.name == "admin" || > + !domain || > + (this.domains && domain.match(this.domains)))) { > + var msg = "Access granted: " + > + "user = " + subject.user + > + ", groups = [" + subject.groups + "]" + > + ", role = " + this.name + > + ", api = " + api; > + if (domain) > + msg += ", domain = " + domain; > + polkit.log(msg); > + return true > + } > + > + return false; > + }; > +} > + > + > +/* Basic operations and monitoring on a limited set of domains. */ > +var userA = new Role("userA"); > +userA.domains = /^a/; > +userA.users = ["userA1", "userA2", "userA3", "multiUser"]; > +userA.groups = ["groupA1", "groupA2"]; > + > +var userB = new Role("userB"); > +userB.domains = /^b/; > +userB.users = ["userB1", "userB2", "userB3", "multiUser"]; > +userB.groups = ["groupB1", "groupB2", "multiGroup"]; > + > +var userC = new Role("userC"); > +userC.domains = /^c/; > +userC.users = ["userC1", "userC2", "userC3"]; > +userC.groups = ["groupC1", "groupC2", "multiGroup"]; > + > +/* Same as users but on any domain. */ > +var operator = new Role("operator"); > +operator.domains = /.*/; > +operator.users = ["powerUser1", "powerUser2"]; > +operator.groups = ["powerGroup1", "powerGroup2", "powerGroup3"]; > + > +var users = [operator, userA, userB, userC]; > + > +/* Full access. */ > +var admin = new Role("admin"); > +admin.users = ["adminUser1"]; > +admin.groups = ["adminGroup1"]; > + > + > +restrictedActions = [ > + "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" > +]; > + > +polkit.addRule(function(action, subject) { > + if (action.id.indexOf("org.libvirt.api.") != 0) > + return polkit.Result.NOT_HANDLED; > + > + var api = action.id.replace("org.libvirt.api.", ""); > + var domain = action.lookup("domain_name"); > + > + if (admin.check(subject, api, domain)) > + return polkit.Result.YES; > + > + if (restrictedActions.indexOf(api) < 0) > + return polkit.Result.NOT_HANDLED; > + > + for (var i = 0; i < users.length; i++) { > + if (users[i].check(subject, api, domain)) > + return polkit.Result.YES; > + } > + > + return polkit.Result.NO; > +}); > diff --git a/libvirt.spec.in b/libvirt.spec.in > index 78a4cc3..6f6b191 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/ > -- ACK Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list