|
|
43fe83 |
From 87ab326e99c0c6b556bfff54a6e4e9bd09faa495 Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <87ab326e99c0c6b556bfff54a6e4e9bd09faa495.1377873638.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: "Daniel P. Berrange" <berrange@redhat.com>
|
|
|
43fe83 |
Date: Tue, 13 Aug 2013 11:38:26 +0100
|
|
|
43fe83 |
Subject: [PATCH] Add info about access control checks into API reference
|
|
|
43fe83 |
|
|
|
43fe83 |
For https://bugzilla.redhat.com/show_bug.cgi?id=700443
|
|
|
43fe83 |
|
|
|
43fe83 |
So that app developers / admins know what access control checks
|
|
|
43fe83 |
are performed for each API, this patch extends the API docs
|
|
|
43fe83 |
generator to include details of the ACLs for each.
|
|
|
43fe83 |
|
|
|
43fe83 |
The gendispatch.pl script is extended so that it generates
|
|
|
43fe83 |
a simple XML describing ACL rules, eg.
|
|
|
43fe83 |
|
|
|
43fe83 |
<aclinfo>
|
|
|
43fe83 |
...
|
|
|
43fe83 |
<api name='virConnectNumOfDomains'>
|
|
|
43fe83 |
<check object='connect' perm='search_domains'/>
|
|
|
43fe83 |
<filter object='domain' perm='getattr'/>
|
|
|
43fe83 |
</api>
|
|
|
43fe83 |
<api name='virDomainAttachDeviceFlags'>
|
|
|
43fe83 |
<check object='domain' perm='write'/>
|
|
|
43fe83 |
<check object='domain' perm='save' flags='!VIR_DOMAIN_AFFECT_CONFIG|VIR_DOMAIN_AFFECT_LIVE'/>
|
|
|
43fe83 |
<check object='domain' perm='save' flags='VIR_DOMAIN_AFFECT_CONFIG'/>
|
|
|
43fe83 |
</api>
|
|
|
43fe83 |
...
|
|
|
43fe83 |
</aclinfo>
|
|
|
43fe83 |
|
|
|
43fe83 |
The newapi.xsl template loads the XML files containing the ACL
|
|
|
43fe83 |
rules and generates a short block of HTML for each API describing
|
|
|
43fe83 |
the parameter checks and return value filters (if any).
|
|
|
43fe83 |
|
|
|
43fe83 |
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
|
|
43fe83 |
(cherry picked from commit 664ab2801dfcb8e72fc4408cc50c279bf74e47a2)
|
|
|
43fe83 |
---
|
|
|
43fe83 |
.gitignore | 3 +++
|
|
|
43fe83 |
docs/libvirt.css | 14 +++++++++++
|
|
|
43fe83 |
docs/newapi.xsl | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
43fe83 |
src/Makefile.am | 22 ++++++++++++++--
|
|
|
43fe83 |
src/rpc/gendispatch.pl | 59 ++++++++++++++++++++++++++++++++++++++++---
|
|
|
43fe83 |
5 files changed, 160 insertions(+), 6 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/docs/libvirt.css b/docs/libvirt.css
|
|
|
43fe83 |
index 8a00d12..ed67b2f 100644
|
|
|
43fe83 |
--- a/docs/libvirt.css
|
|
|
43fe83 |
+++ b/docs/libvirt.css
|
|
|
43fe83 |
@@ -477,3 +477,17 @@ dl.variablelist > dt {
|
|
|
43fe83 |
dl.variablelist > dt:after {
|
|
|
43fe83 |
content: ": ";
|
|
|
43fe83 |
}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+table.acl {
|
|
|
43fe83 |
+ margin: 1em;
|
|
|
43fe83 |
+ border-spacing: 0px;
|
|
|
43fe83 |
+ border: 1px solid #ccc;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+table.acl tr, table.acl td {
|
|
|
43fe83 |
+ padding: 0.3em;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+table.acl thead {
|
|
|
43fe83 |
+ background: #ddd;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
diff --git a/docs/newapi.xsl b/docs/newapi.xsl
|
|
|
43fe83 |
index d5b210e..58f12eb 100644
|
|
|
43fe83 |
--- a/docs/newapi.xsl
|
|
|
43fe83 |
+++ b/docs/newapi.xsl
|
|
|
43fe83 |
@@ -29,6 +29,69 @@
|
|
|
43fe83 |
<xsl:variable name="htmldir">html</xsl:variable>
|
|
|
43fe83 |
<xsl:variable name="href_base">../</xsl:variable>
|
|
|
43fe83 |
|
|
|
43fe83 |
+ <xsl:variable name="acls">
|
|
|
43fe83 |
+ <xsl:copy-of select="document('../src/libvirt_access.xml')/aclinfo/api"/>
|
|
|
43fe83 |
+ </xsl:variable>
|
|
|
43fe83 |
+ <xsl:variable name="qemuacls">
|
|
|
43fe83 |
+ <xsl:copy-of select="document('../src/libvirt_access_qemu.xml')/aclinfo/api"/>
|
|
|
43fe83 |
+ </xsl:variable>
|
|
|
43fe83 |
+ <xsl:variable name="lxcacls">
|
|
|
43fe83 |
+ <xsl:copy-of select="document('../src/libvirt_access_lxc.xml')/aclinfo/api"/>
|
|
|
43fe83 |
+ </xsl:variable>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ <xsl:template name="aclinfo">
|
|
|
43fe83 |
+ <xsl:param name="api"/>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ <xsl:if test="count(exsl:node-set($acls)/api[@name=$api]/check) > 0">
|
|
|
43fe83 |
+ Access control parameter checks
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ Object
|
|
|
43fe83 |
+ Permission
|
|
|
43fe83 |
+ Condition
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ <xsl:apply-templates select="exsl:node-set($acls)/api[@name=$api]/check" mode="acl"/>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ </xsl:if>
|
|
|
43fe83 |
+ <xsl:if test="count(exsl:node-set($acls)/api[@name=$api]/filter) > 0">
|
|
|
43fe83 |
+ Access control return value filters
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ Object
|
|
|
43fe83 |
+ Permission
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ <xsl:apply-templates select="exsl:node-set($acls)/api[@name=$api]/filter" mode="acl"/>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ </xsl:if>
|
|
|
43fe83 |
+ </xsl:template>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ <xsl:template match="check" mode="acl">
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ <xsl:value-of select="@object"/>
|
|
|
43fe83 |
+ <xsl:value-of select="@perm"/>
|
|
|
43fe83 |
+ <xsl:choose>
|
|
|
43fe83 |
+ <xsl:when test="@flags">
|
|
|
43fe83 |
+ <xsl:value-of select="@flags"/>
|
|
|
43fe83 |
+ </xsl:when>
|
|
|
43fe83 |
+ <xsl:otherwise>
|
|
|
43fe83 |
+ -
|
|
|
43fe83 |
+ </xsl:otherwise>
|
|
|
43fe83 |
+ </xsl:choose>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ </xsl:template>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ <xsl:template match="filter" mode="acl">
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ <xsl:value-of select="@object"/>
|
|
|
43fe83 |
+ <xsl:value-of select="@perm"/>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ </xsl:template>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
<xsl:template name="navbar">
|
|
|
43fe83 |
<xsl:variable name="previous" select="preceding-sibling::file[1]"/>
|
|
|
43fe83 |
<xsl:variable name="next" select="following-sibling::file[1]"/>
|
|
|
43fe83 |
@@ -553,6 +616,11 @@
|
|
|
43fe83 |
</xsl:if>
|
|
|
43fe83 |
|
|
|
43fe83 |
</xsl:if>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ <xsl:call-template name="aclinfo">
|
|
|
43fe83 |
+ <xsl:with-param name="api" select="$name"/>
|
|
|
43fe83 |
+ </xsl:call-template>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
</xsl:template>
|
|
|
43fe83 |
|
|
|
43fe83 |
<xsl:template match="exports" mode="toc">
|
|
|
43fe83 |
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
|
43fe83 |
index 12ca204..8c6f068 100644
|
|
|
43fe83 |
--- a/src/Makefile.am
|
|
|
43fe83 |
+++ b/src/Makefile.am
|
|
|
43fe83 |
@@ -826,6 +826,11 @@ ACCESS_DRIVER_SYM_FILES = \
|
|
|
43fe83 |
libvirt_access_qemu.syms \
|
|
|
43fe83 |
libvirt_access_lxc.syms
|
|
|
43fe83 |
|
|
|
43fe83 |
+ACCESS_DRIVER_API_FILES = \
|
|
|
43fe83 |
+ libvirt_access.xml \
|
|
|
43fe83 |
+ libvirt_access_qemu.xml \
|
|
|
43fe83 |
+ libvirt_access_lxc.xml
|
|
|
43fe83 |
+
|
|
|
43fe83 |
ACCESS_DRIVER_SOURCES = \
|
|
|
43fe83 |
access/viraccessperm.h access/viraccessperm.c \
|
|
|
43fe83 |
access/viraccessmanager.h access/viraccessmanager.c \
|
|
|
43fe83 |
@@ -1492,8 +1497,8 @@ EXTRA_DIST += $(ACCESS_DRIVER_POLKIT_SOURCES)
|
|
|
43fe83 |
endif
|
|
|
43fe83 |
|
|
|
43fe83 |
|
|
|
43fe83 |
-BUILT_SOURCES += $(ACCESS_DRIVER_GENERATED)
|
|
|
43fe83 |
-CLEANFILES += $(ACCESS_DRIVER_GENERATED)
|
|
|
43fe83 |
+BUILT_SOURCES += $(ACCESS_DRIVER_GENERATED) $(ACCESS_DRIVER_API_FILES)
|
|
|
43fe83 |
+CLEANFILES += $(ACCESS_DRIVER_GENERATED) $(ACCESS_DRIVER_API_FILES)
|
|
|
43fe83 |
|
|
|
43fe83 |
libvirt_access.syms: $(srcdir)/rpc/gendispatch.pl \
|
|
|
43fe83 |
$(REMOTE_PROTOCOL) Makefile.am
|
|
|
43fe83 |
@@ -1508,6 +1513,19 @@ libvirt_access_lxc.syms: $(srcdir)/rpc/gendispatch.pl \
|
|
|
43fe83 |
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl --mode=aclsym \
|
|
|
43fe83 |
lxc LXC $(LXC_PROTOCOL) > $@
|
|
|
43fe83 |
|
|
|
43fe83 |
+libvirt_access.xml: $(srcdir)/rpc/gendispatch.pl \
|
|
|
43fe83 |
+ $(REMOTE_PROTOCOL) Makefile.am
|
|
|
43fe83 |
+ $(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl --mode=aclapi \
|
|
|
43fe83 |
+ remote REMOTE $(REMOTE_PROTOCOL) > $@
|
|
|
43fe83 |
+libvirt_access_qemu.xml: $(srcdir)/rpc/gendispatch.pl \
|
|
|
43fe83 |
+ $(QEMU_PROTOCOL) Makefile.am
|
|
|
43fe83 |
+ $(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl --mode=aclapi \
|
|
|
43fe83 |
+ qemu QEMU $(QEMU_PROTOCOL) > $@
|
|
|
43fe83 |
+libvirt_access_lxc.xml: $(srcdir)/rpc/gendispatch.pl \
|
|
|
43fe83 |
+ $(LXC_PROTOCOL) Makefile.am
|
|
|
43fe83 |
+ $(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl --mode=aclapi \
|
|
|
43fe83 |
+ lxc LXC $(LXC_PROTOCOL) > $@
|
|
|
43fe83 |
+
|
|
|
43fe83 |
$(srcdir)/access/viraccessapicheck.h: $(srcdir)/rpc/gendispatch.pl \
|
|
|
43fe83 |
$(REMOTE_PROTOCOL) Makefile.am
|
|
|
43fe83 |
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl --mode=aclheader \
|
|
|
43fe83 |
diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
|
|
|
43fe83 |
index 8f41771..ac0c7ab 100755
|
|
|
43fe83 |
--- a/src/rpc/gendispatch.pl
|
|
|
43fe83 |
+++ b/src/rpc/gendispatch.pl
|
|
|
43fe83 |
@@ -41,8 +41,8 @@ my $res = GetOptions("mode=s" => \$mode);
|
|
|
43fe83 |
die "cannot parse command line options" unless $res;
|
|
|
43fe83 |
|
|
|
43fe83 |
die "unknown mode '$mode', expecting 'client', 'server', " .
|
|
|
43fe83 |
- "'aclheader', 'aclbody', 'aclsym' or 'debug'"
|
|
|
43fe83 |
- unless $mode =~ /^(client|server|aclheader|aclbody|aclsym|debug)$/;
|
|
|
43fe83 |
+ "'aclheader', 'aclbody', 'aclsym', 'aclapi' or 'debug'"
|
|
|
43fe83 |
+ unless $mode =~ /^(client|server|aclheader|aclbody|aclsym|aclapi|debug)$/;
|
|
|
43fe83 |
|
|
|
43fe83 |
my $structprefix = shift or die "missing struct prefix argument";
|
|
|
43fe83 |
my $procprefix = shift or die "missing procedure prefix argument";
|
|
|
43fe83 |
@@ -351,6 +351,13 @@ if ($mode eq "aclsym") {
|
|
|
43fe83 |
# Automatically generated by gendispatch.pl.
|
|
|
43fe83 |
# Do not edit this file. Any changes you make will be lost.
|
|
|
43fe83 |
__EOF__
|
|
|
43fe83 |
+} elsif ($mode eq "aclapi") {
|
|
|
43fe83 |
+ print <<__EOF__;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ - Automatically generated by gendispatch.pl.
|
|
|
43fe83 |
+ - Do not edit this file. Any changes you make will be lost.
|
|
|
43fe83 |
+ -->
|
|
|
43fe83 |
+__EOF__
|
|
|
43fe83 |
} else {
|
|
|
43fe83 |
print <<__EOF__;
|
|
|
43fe83 |
/* Automatically generated by gendispatch.pl.
|
|
|
43fe83 |
@@ -1641,7 +1648,8 @@ elsif ($mode eq "client") {
|
|
|
43fe83 |
}
|
|
|
43fe83 |
} elsif ($mode eq "aclheader" ||
|
|
|
43fe83 |
$mode eq "aclbody" ||
|
|
|
43fe83 |
- $mode eq "aclsym") {
|
|
|
43fe83 |
+ $mode eq "aclsym" ||
|
|
|
43fe83 |
+ $mode eq "aclapi") {
|
|
|
43fe83 |
my %generate = map { $_ => 1 } @autogen;
|
|
|
43fe83 |
my @keys = keys %calls;
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -1667,6 +1675,7 @@ elsif ($mode eq "client") {
|
|
|
43fe83 |
foreach my $hdr (@headers) {
|
|
|
43fe83 |
print "#include \"$hdr\"\n";
|
|
|
43fe83 |
}
|
|
|
43fe83 |
+ print "\n";
|
|
|
43fe83 |
} elsif ($mode eq "aclbody") {
|
|
|
43fe83 |
my $header = shift;
|
|
|
43fe83 |
print "#include <config.h>\n";
|
|
|
43fe83 |
@@ -1676,8 +1685,12 @@ elsif ($mode eq "client") {
|
|
|
43fe83 |
print "#include \"virerror.h\"\n";
|
|
|
43fe83 |
print "\n";
|
|
|
43fe83 |
print "#define VIR_FROM_THIS VIR_FROM_ACCESS\n";
|
|
|
43fe83 |
+ print "\n";
|
|
|
43fe83 |
+ } elsif ($mode eq "aclapi") {
|
|
|
43fe83 |
+ print "<aclinfo>\n";
|
|
|
43fe83 |
+ } else {
|
|
|
43fe83 |
+ print "\n";
|
|
|
43fe83 |
}
|
|
|
43fe83 |
- print "\n";
|
|
|
43fe83 |
|
|
|
43fe83 |
foreach (@keys) {
|
|
|
43fe83 |
my $call = $calls{$_};
|
|
|
43fe83 |
@@ -1699,6 +1712,8 @@ elsif ($mode eq "client") {
|
|
|
43fe83 |
print $apiname . "CheckACL;\n";
|
|
|
43fe83 |
}
|
|
|
43fe83 |
print $apiname . "EnsureACL;\n";
|
|
|
43fe83 |
+ } elsif ($mode eq "aclapi") {
|
|
|
43fe83 |
+ &generate_aclapi($call);
|
|
|
43fe83 |
} else {
|
|
|
43fe83 |
&generate_acl($call, $call->{acl}, "Ensure");
|
|
|
43fe83 |
if (defined $call->{aclfilter}) {
|
|
|
43fe83 |
@@ -1835,5 +1850,41 @@ elsif ($mode eq "client") {
|
|
|
43fe83 |
print "}\n\n";
|
|
|
43fe83 |
}
|
|
|
43fe83 |
}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ sub generate_aclapi {
|
|
|
43fe83 |
+ my $call = shift;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ my $apiname = "vir" . $call->{ProcName};
|
|
|
43fe83 |
+ if ($structprefix eq "qemu") {
|
|
|
43fe83 |
+ $apiname =~ s/virDomain/virDomainQemu/;
|
|
|
43fe83 |
+ } elsif ($structprefix eq "lxc") {
|
|
|
43fe83 |
+ $apiname =~ s/virDomain/virDomainLxc/;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ print " <api name='$apiname'>\n";
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ my $acl = $call->{acl};
|
|
|
43fe83 |
+ foreach (@{$acl}) {
|
|
|
43fe83 |
+ my @bits = split /:/;
|
|
|
43fe83 |
+ print "
|
|
|
43fe83 |
+ if (defined $bits[2]) {
|
|
|
43fe83 |
+ print " flags='$bits[2]'";
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ print "/>\n";
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ my $aclfilter = $call->{aclfilter};
|
|
|
43fe83 |
+ foreach (@{$aclfilter}) {
|
|
|
43fe83 |
+ my @bits = split /:/;
|
|
|
43fe83 |
+ print " <filter object='$bits[0]' perm='$bits[1]'/>\n";
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ print " </api>\n";
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if ($mode eq "aclapi") {
|
|
|
43fe83 |
+ print "</aclinfo>\n";
|
|
|
43fe83 |
}
|
|
|
43fe83 |
}
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|