On 08/08/2013 05:27 AM, Daniel P. Berrange wrote: > From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> > > This adds two new pages to the website, acl.html describing > the general access control framework and permissions models, > and aclpolkit.html describing the use of polkit as an > access control driver. > > page.xsl is modified to support a new syntax > > <div id="include" filename="somefile.htmlinc"/> > > which will cause the XSL transform to replace that <div> > with the contents of 'somefile.htmlinc'. We use this in > the acl.html.in file, to pull the table of permissions > for each libvirt object. This table is autogenerated > from the enums in src/access/viraccessperms.h by the > genaclperms.pl script. > > newapi.xsl is modified so that the list of permissions > checks shown against each API will link to the description > of the permissions in acl.html > > Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> > --- > .gitignore | 1 + > docs/Makefile.am | 12 +- > docs/acl.html.in | 100 ++++++++++++ > docs/aclpolkit.html.in | 414 +++++++++++++++++++++++++++++++++++++++++++++++++ > docs/auth.html.in | 6 +- > docs/genaclperms.pl | 124 +++++++++++++++ > docs/newapi.xsl | 4 +- > docs/page.xsl | 11 ++ > docs/sitemap.html.in | 10 ++ > 9 files changed, 677 insertions(+), 5 deletions(-) > create mode 100644 docs/acl.html.in > create mode 100644 docs/aclpolkit.html.in > create mode 100644 docs/genaclperms.pl [I still need to look into why, in a clean checkout, 'make distcheck' fails when 'make all distcheck' passes, but that shoudln't hold up this patch, whether or not this patch aggravates the issue] > +aclperms.htmlinc: $(top_srcdir)/src/access/viraccessperm.h \ > + genaclperms.pl Makefile.am > + $(PERL) genaclperms.pl $< > $@ Did you test a VPATH build? > + <p> > + In a default configuration, the libvirtd daemon have three levels s/have/has/ > + of access control. All connections start off in an unauthenticated > + state, where the only API operations allowed are those required > + to complete authentication. After successful authentication, a > + connection either has full, unrestricted access to all libvirt > + API calls, or is locked down to only "read only" operations, > + according to what socket a client connection originated on. > + </p> > + > + <p> > + The access control framework allows authenticated connections to > + have fine grained permission rules to be defined by the administrator. > + Every API call in libvirt has a set of permissions that will > + be validated against the object being used. For example, the > + <code>virDomainSetSchedulerParametersFlags</code> method will > + check whether the client user has the <code>write</code> > + permission on the <code>domain</code> object instance passed > + in as a parameter. Further permissions will also be checked > + if certain flags are set in the API call. In addition to > + checks on the object passed into an API call, some methods s/into/in to/ > + will filter their results. For example the <code>virConnectListAllDomains</code> > + method will check the <code>search_domains</code> on the <code>connect</code> > + object, but will also filter the returned <code>domain</code> > + objects to only those on which the client user has the > + <code>getattr</code> permission. > + </p> > + > + <h2><a name="drivers">Access control drivers</a></h2> > + > + <p> > + The access control framework is designed as a pluggable > + system to enable future integration with arbitrary access > + control technologies. By default, the <code>none</code> > + driver is used, which does not access controll checks at s/not/no/; s/controll/control/ > + all. At this time, libvirt ships with support for using > + <a href="http://www.freedesktop.org/wiki/Software/polkit/">polkit</a> as a real access > + control driver. To learn how to use the polkit access > + driver consult <a href="aclpolkit.html">the configuration > + docs</a>. > + </p> > + > + <p> > + The access driver is configured in the <code>libvirtd.conf</code> > + configuration file, using the <code>access_drivers</code> > + parameter. This parameter accepts an array of access control > + driver names. If more than one access driver is requested, > + then all must succeed in order for access to be granted. > + To enable 'polkit' as the driver > + </p> > + > + <pre> > +# augtool -s set '/files/etc/libvirt/libvirtd.conf/access_drivers[1]' polkit > + </pre> > + > + <p> > + And to reset back to the default (no-op) driver > + </p> > + > + > + <pre> > +# augtool -s rm /files/etc/libvirt/libvirtd.conf/access_drivers > + </pre> > + > + <p> > + <strong>Note:</strong> changes to libvirtd.conf require that > + the libvirtd daemon be restarted. Isn't sending SIGHUP sufficient, or does it have to be a full restart? > + </p> > + > + <h2><a name="perms">Objects and permissions</a></h2> > + > + <p> > + Libvirt applies access control to all the main object > + types in its API. Each object type, in turn, has a set > + of permissions defined. To determine what permissions > + are checked for specific API call, consult the > + <a href="html/libvirt-libvirt.html">API reference manual</a> > + documentation for the API in question. > + </p> > + > + <div id="include" filename="aclperms.htmlinc"/> > + > + </body> > +</html> > diff --git a/docs/aclpolkit.html.in b/docs/aclpolkit.html.in > new file mode 100644 > index 0000000..d7be0bd > --- /dev/null > +++ b/docs/aclpolkit.html.in > @@ -0,0 +1,414 @@ > +<?xml version="1.0" encoding="UTF-8"?> > +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> > +<html xmlns="http://www.w3.org/1999/xhtml"> > + <body> > + <h1>Polkit access control</h1> > + > + <p> > + Libvirt's client <a href="acl.html">access control framework</a> allows > + administrators to setup fine grained permission rules across client users, > + managed objects and API operations. This allows client connections > + to be locked down to a minimal set of privileges. The polkit driver > + provides a simple implementation of the access control framework s/$/./ > + </p> > + > + <ul id="toc"></ul> > + > + <h2><a name="intro">Introduction</a></h2> > + > + <p> > + A default install of libvirt will typically use > + <a href="http://www.freedesktop.org/wiki/Software/polkit/">polkit</a> > + to authenticate the initial user connection to libvirtd. This is a > + very coarse grained check though either allowing full read-write s/though/though,/ > + access to all APIs, or just read-only access. The polkit access > + control driver in libvirt builds on this capability to allow for > + fine grained control over the operations a user may perform on an > + object. > + </p> > + > + <h2><a name="perms">Permission names</a></h2> > + > + <p> > + The libvirt <a href="acl.html#perms">object names and permission names</a> > + are mapped onto polkit action names using the simple pattern: > + </p> > + > + <pre>org.libvirt.api.$object.$permission > +</pre> > + > + <p> > + The only caveat is that any underscore characters in the > + object or permission names are converted to hyphens. So, > + for example, the <code>search_storage_vols</code> permission > + on the <code>storage_pool</code> object maps to the polkit > + action: > + </p> > + <pre>org.libvirt.api.storage-pool.search-storage-vols > +</pre> > + > + <p> > + The default policy for any permission which corresponds to > + an "read only" operation, is to allow access. All other s/an/a/ > + permissions default to deny access. > + </p> > + > + <h2><a name="attrs">Object identity attributes</a></h2> > + > + <p> > + To allow polkit authorization rules to be written to match > + against individual object instances, libvirt provides a number > + of authorization detail attributes when performing a permission > + check. The set of attributes varies according to the type > + of object being checked > + </p> > + > + <h3><a name="object_connect">virConnectPtr</a></h3> > + <table class="acl"> > + > + <h3><a name="object_secret">virSecretPtr</a></h3> > + <table class="acl"> > + <tr> > + <td></td> > + <td></td> > + </tr> Drop the empty row. > + > + <h2><a name="user">User identity attributes</a></h2> > + > + <p> > + At this point in time, the only attribute provided by > + libvirt to identify the user invoking the operation > + is the PID of the client program. This means that the > + polkit access control driver is only useful if connections > + to libvirt are restricted to its UNIX domain socket. If > + connections are being made to a TCP socket, no identifying > + information is available & access will be denied. s/&/and/ > + Also note that if the client is connecting via an SSH > + tunnel, it is the local SSH user that will be identified. > + In future versions, it is expected that more information > + about the client user will be provided, including the > + SASAL / Kerberos username and/or x509 distinguished s/SASAL/SASL/ > + name obtained from the authentication provider in use. > + </p> > + > + > + <h2><a name="checks">Writing acces control policies</a></h2> > + > + <p> > + If using versions of polkit prior to 0.106 then it is only > + possible to validate (user, permission) pairs via the <code>.pkla</code> > + files. Fully validation of the (user, permission, object) triple > + requires the new JavaScript <code>.rules</code> support that > + was introduced in version 0.106. That latter is what will be s/That/The/ > + described here. > + </p> > + > + <p> > + Libvirt does not ship any rules files by default. It merely > + provides a definition of the default behaviour for each > + action (permission). As noted earlier, permissions which > + correspond to read-only operations in libvirt will be allowed > + to all users by default; everything else is denied by default. > + Defining custom rules requires creation of a file in the > + <code>/etc/polkit-1/rules.d</code> directory with a name > + chosen by the administrator (<code>100-libvirt-acl.rules</code> > + would be a reasonable choice). See the <code>polkit(8)</code> > + manual page for a description of how to write these files > + in general. The key idea is to create a file containing > + something like > + </p> > + > + <pre> > + polkit.addRule(function(action, subject) { > + ....logic to check 'action' and 'subject'... > + }); > + </pre> > + > + <p> > + In this code snippet above, the <code>action</code> object > + instance will represent the libvirt permission being checked > + along with identifying attributes for the object it is being > + applied to. The <code>subject</code> meanwhile will identify > + the libvirt client app (with the caveat above about it only > + dealing with local clients connected via the UNIX socket). > + On the <code>action</code> object, the permission name is > + accessible via the <code>id</code> attribute, while the > + object identifying attributes are exposed via a set of > + attributes with the naming convention <code>_detail_[attrname]</code>. > + For example, the 'domain_name' attribute would be exposed via > + a property <code>_detail_domain_name</code>. > + </p> > + > + <h3><a name="exconnect">Example: restricting ability to connect to drivers</a></h3> > + > + <p> > + Consider a local user <code>berrange</code> > + who has been granted permission to connect to libvirt in > + full read-write mode. The goal is to only allow them to > + use the <code>QEMU</code> driver and not the Xen or LXC > + drivers which are also available in libvirtd. > + To achieve this we need to write a rule which checks > + whether the <code>_detail_connect_driver</code> attribute > + is <code>QEMU</code>, and match on a action > + name of <code>org.libvirt.api.connect.getattr</code>. Using > + the javascript rules format, this ends up written as > + </p> > + > + <pre> > +polkit.addRule(function(action, subject) { > + if (action.id == "org.libvirt.api.connect.getattr" && > + subject.user == "berrange") { > + if (action._detail_connect_driver == 'QEMU') { > + return polkit.Result.YES; > + } else { > + return polkit.Result.NO; > + } > + } This function has no return statement when the initial 'if' is not satisfied; is that valid? > +}); > + </pre> > + > + <h3><a name="exdomain">Example: restricting access to a single domain</a></h3> > + > + <p> > + Consider a local user <code>berrange</code> > + who has been granted permission to connect to libvirt in > + full read-write mode. The goal is to only allow them to > + see the domain called <code>demo</code> on the LXC driver. > + To achieve this we need to write a rule which checks > + whether the <code>_detail_connect_driver</code> attribute > + is <code>LXC</code> and the <code>_detail_domain_name</code> > + attribute is <code>demo</code>, and match on a action s/a /an / > + name of <code>org.libvirt.api.domain.getattr</code>. Using > + the javascript rules format, this ends up written as > + </p> > + > + <pre> > +polkit.addRule(function(action, subject) { > + if (action.id == "org.libvirt.api.domain.getattr" && > + subject.user == "berrange") { > + if (action._detail_connect_driver == 'LXC' && > + action._detail_domain_name == 'busy') { > + return polkit.Result.YES; > + } else { > + return polkit.Result.NO; > + } > + } Again, what happens when you fall off the end of a rule without a return? > +}); > + </pre> > + </body> > +</html> > diff --git a/docs/auth.html.in b/docs/auth.html.in > index e5703c7..37f2978 100644 > --- a/docs/auth.html.in > +++ b/docs/auth.html.in > @@ -2,12 +2,14 @@ > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> > <html xmlns="http://www.w3.org/1999/xhtml"> > <body> > - <h1 >Authentication & access control</h1> > + <h1>Connection authentication</h1> > <p> > When connecting to libvirt, some connections may require client > authentication before allowing use of the APIs. The set of possible > authentication mechanisms is administrator controlled, independent > - of applications using libvirt. > + of applications using libvirt. Once authenticated, libvirt can apply > + fine grained <a href="acl.html">access control</a> to the operations > + performed by a client. > </p> > > <ul id="toc"></ul> > diff --git a/docs/genaclperms.pl b/docs/genaclperms.pl > new file mode 100644 > index 0000000..244a68e > --- /dev/null > +++ b/docs/genaclperms.pl 'chmod +x' before pushing, to match the permissions of all our other .pl files. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Attachment:
signature.asc
Description: OpenPGP digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list