aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2010-02-21 17:45:55 -0800
committerRuss Allbery <rra@stanford.edu>2010-02-21 17:45:55 -0800
commit60210334fa3dbd5dd168199063c6ee850d750d0c (patch)
tree31e832ba6788076075d38e20ffd27ebf09430407 /server
parente571a8eb96f42de5a114cf11ff1c3d63e5a8d301 (diff)
Imported Upstream version 0.10
Diffstat (limited to 'server')
-rwxr-xr-xserver/keytab-backend65
-rw-r--r--server/keytab-backend.8185
-rwxr-xr-xserver/wallet-admin108
-rw-r--r--server/wallet-admin.8269
-rwxr-xr-xserver/wallet-backend126
-rw-r--r--server/wallet-backend.8357
-rwxr-xr-xserver/wallet-report203
-rw-r--r--server/wallet-report.8253
8 files changed, 1454 insertions, 112 deletions
diff --git a/server/keytab-backend b/server/keytab-backend
index 06fed3d..7b6adb4 100755
--- a/server/keytab-backend
+++ b/server/keytab-backend
@@ -1,5 +1,4 @@
#!/usr/bin/perl
-our $ID = q$Id$;
#
# keytab-backend -- Extract keytabs from the KDC without changing the key.
#
@@ -18,7 +17,8 @@ our $ID = q$Id$;
# The keytab for the extracted principal will be printed to standard output.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2006, 2007, 2008, 2010
+# Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -156,6 +156,10 @@ __END__
# Documentation
##############################################################################
+=for stopwords
+keytab-backend keytabs KDC keytab kadmin.local -norandkey ktadd remctld
+auth Allbery rekeying
+
=head1 NAME
keytab-backend - Extract keytabs from the KDC without changing the key
@@ -166,27 +170,28 @@ B<keytab-backend> retrieve I<principal>
=head1 DESCRIPTION
-B<keytab-backend> retrieves a keytab for an existing principal from the KDC
-database without changing the current key. It allows generation of a keytab
-for a service without rekeying that service. It requires a B<kadmin.local>
-patched to support the B<-norandkey> option to B<ktadd>.
+B<keytab-backend> retrieves a keytab for an existing principal from the
+KDC database without changing the current key. It allows generation of a
+keytab for a service without rekeying that service. It requires a
+B<kadmin.local> patched to support the B<-norandkey> option to B<ktadd>.
-This script is intended to run under B<remctld>. On success, it prints the
-keytab to standard output, logs a success message to syslog (facility auth,
-priority info), and exits with status 0. On failure, it prints out an error
-message, logs an error to syslog (facility auth, priority err), and exits
-with a non-zero status.
+This script is intended to run under B<remctld>. On success, it prints
+the keytab to standard output, logs a success message to syslog (facility
+auth, priority info), and exits with status 0. On failure, it prints out
+an error message, logs an error to syslog (facility auth, priority err),
+and exits with a non-zero status.
The principal is checked for basic sanity (only accepting alphanumerics,
-C<_>, and C<-> with an optional instance and then only alphanumerics, C<_>,
-C<->, and C<.> in the realm) and then checked against a configuration file
-that lists regexes of principals that can be retrieved. When deploying this
-software, limit as tightly as possible which principals can be downloaded in
-this fashion. Generally only shared service principals used on multiple
-systems should be made available in this way.
+C<_>, and C<-> with an optional instance and then only alphanumerics,
+C<_>, C<->, and C<.> in the realm) and then checked against a
+configuration file that lists regexes of principals that can be retrieved.
+When deploying this software, limit as tightly as possible which
+principals can be downloaded in this fashion. Generally only shared
+service principals used on multiple systems should be made available in
+this way.
-B<keytab-backend> does not do any authorization checks. Those should be done
-by B<remctld> before it is called.
+B<keytab-backend> does not do any authorization checks. Those should be
+done by B<remctld> before it is called.
=head1 FILES
@@ -194,19 +199,19 @@ by B<remctld> before it is called.
=item F</etc/krb5kdc/allow-extract>
-The configuration file that controls which principals can have their keytabs
-retrieved. Blank lines and lines starting with C<#>, as well as anything
-after C<#> on a line, are ignored. All other lines should be Perl regular
-expressions, one per line, that match principals whose keytabs can be
-retrieved by B<keytab-backend>. Any principal that does not match one of
-those regular expressions cannot be retrieved.
+The configuration file that controls which principals can have their
+keytabs retrieved. Blank lines and lines starting with C<#>, as well as
+anything after C<#> on a line, are ignored. All other lines should be
+Perl regular expressions, one per line, that match principals whose
+keytabs can be retrieved by B<keytab-backend>. Any principal that does
+not match one of those regular expressions cannot be retrieved.
=item F</var/lib/keytabs>
The temporary directory used for creating keytabs. B<keytab-backend> will
-create the keytab in this directory, make sure that was successful, and then
-delete the temporary file after the results have been sent to standard
-output.
+create the keytab in this directory, make sure that was successful, and
+then delete the temporary file after the results have been sent to
+standard output.
=back
@@ -214,8 +219,8 @@ output.
kadmin.local(8), remctld(8)
-This program is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This program is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/server/keytab-backend.8 b/server/keytab-backend.8
new file mode 100644
index 0000000..9dd4e76
--- /dev/null
+++ b/server/keytab-backend.8
@@ -0,0 +1,185 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "KEYTAB-BACKEND 8"
+.TH KEYTAB-BACKEND 8 "2010-02-20" "0.10" "wallet"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+keytab\-backend \- Extract keytabs from the KDC without changing the key
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBkeytab-backend\fR retrieve \fIprincipal\fR
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBkeytab-backend\fR retrieves a keytab for an existing principal from the
+\&\s-1KDC\s0 database without changing the current key. It allows generation of a
+keytab for a service without rekeying that service. It requires a
+\&\fBkadmin.local\fR patched to support the \fB\-norandkey\fR option to \fBktadd\fR.
+.PP
+This script is intended to run under \fBremctld\fR. On success, it prints
+the keytab to standard output, logs a success message to syslog (facility
+auth, priority info), and exits with status 0. On failure, it prints out
+an error message, logs an error to syslog (facility auth, priority err),
+and exits with a non-zero status.
+.PP
+The principal is checked for basic sanity (only accepting alphanumerics,
+\&\f(CW\*(C`_\*(C'\fR, and \f(CW\*(C`\-\*(C'\fR with an optional instance and then only alphanumerics,
+\&\f(CW\*(C`_\*(C'\fR, \f(CW\*(C`\-\*(C'\fR, and \f(CW\*(C`.\*(C'\fR in the realm) and then checked against a
+configuration file that lists regexes of principals that can be retrieved.
+When deploying this software, limit as tightly as possible which
+principals can be downloaded in this fashion. Generally only shared
+service principals used on multiple systems should be made available in
+this way.
+.PP
+\&\fBkeytab-backend\fR does not do any authorization checks. Those should be
+done by \fBremctld\fR before it is called.
+.SH "FILES"
+.IX Header "FILES"
+.IP "\fI/etc/krb5kdc/allow\-extract\fR" 4
+.IX Item "/etc/krb5kdc/allow-extract"
+The configuration file that controls which principals can have their
+keytabs retrieved. Blank lines and lines starting with \f(CW\*(C`#\*(C'\fR, as well as
+anything after \f(CW\*(C`#\*(C'\fR on a line, are ignored. All other lines should be
+Perl regular expressions, one per line, that match principals whose
+keytabs can be retrieved by \fBkeytab-backend\fR. Any principal that does
+not match one of those regular expressions cannot be retrieved.
+.IP "\fI/var/lib/keytabs\fR" 4
+.IX Item "/var/lib/keytabs"
+The temporary directory used for creating keytabs. \fBkeytab-backend\fR will
+create the keytab in this directory, make sure that was successful, and
+then delete the temporary file after the results have been sent to
+standard output.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIkadmin.local\fR\|(8), \fIremctld\fR\|(8)
+.PP
+This program is part of the wallet system. The current version is
+available from <http://www.eyrie.org/~eagle/software/wallet/>.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Russ Allbery <rra@stanford.edu>
diff --git a/server/wallet-admin b/server/wallet-admin
index 4c27e9b..828cfc5 100755
--- a/server/wallet-admin
+++ b/server/wallet-admin
@@ -1,10 +1,9 @@
#!/usr/bin/perl -w
-our $ID = q$Id$;
#
-# wallet-admin -- Wallet server administrative commands.
+# wallet-backend -- Wallet server administrative commands.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -43,11 +42,11 @@ sub command {
unless $args[0] =~ /^[^\@\s]+\@\S+$/;
$admin->initialize (@args) or die $admin->error, "\n";
} elsif ($command eq 'list') {
- die "too many arguments to list\n" if @args > 1;
+ die "too many arguments to list\n" if @args > 4;
die "too few arguments to list\n" if @args < 1;
- my ($type) = @args;
+ my ($type, $subtype, @search) = @args;
if ($type eq 'objects') {
- my @objects = $admin->list_objects;
+ my @objects = $admin->list_objects ($subtype, @search);
if (!@objects and $admin->error) {
die $admin->error, "\n";
}
@@ -55,7 +54,7 @@ sub command {
print join (' ', @$object), "\n";
}
} elsif ($type eq 'acls') {
- my @acls = $admin->list_acls;
+ my @acls = $admin->list_acls ($subtype, @search);
if (!@acls and $admin->error) {
die $admin->error, "\n";
}
@@ -65,6 +64,22 @@ sub command {
} else {
die "only objects or acls are supported for list\n";
}
+ } elsif ($command eq 'report') {
+ die "too few arguments to report\n" if @args < 1;
+ my $report = shift @args;
+ if ($report eq 'owners') {
+ die "too many arguments to report owners\n" if @args > 2;
+ die "too few arguments to report owners\n" if @args < 2;
+ my @lines = $admin->report_owners (@args);
+ if (!@lines and $admin->error) {
+ die $admin->error, "\n";
+ }
+ for my $line (@lines) {
+ print join (' ', @$line), "\n";
+ }
+ } else {
+ die "unknown report type $report\n";
+ }
} elsif ($command eq 'register') {
die "too many arguments to register\n" if @args > 3;
die "too few arguments to register\n" if @args < 3;
@@ -95,6 +110,9 @@ __END__
wallet-admin - Wallet server administrative commands
+=for stopwords
+metadata ACL hostname backend acl acls wildcard SQL Allbery
+
=head1 SYNOPSIS
B<wallet-admin> I<command> [I<args> ...]
@@ -141,10 +159,10 @@ Before running C<initialize>, the wallet system has to be configured. See
Wallet::Config(3) for more details. Depending on the database backend
used, the database may also have to be created in advance.
-=item list (acls | objects)
+=item list (acls | objects) [ <searchtype> [ <arg> ... ] ]
-Returns a list of all ACLs or objects in the database. ACLs will be
-listed in the form:
+Returns a list of ACLs or objects in the database. ACLs will be listed
+in the form:
<name> (ACL ID: <id>)
@@ -156,6 +174,51 @@ be listed in the form:
In both cases, there will be one line per ACL or object.
+If no search type is given, all the ACLs or objects in the database will
+be returned. If a search type (and possible search arguments) are given,
+then the ACLs or objects will be limited to those that match the search.
+
+The currently supported object search types are:
+
+=over 4
+
+=item list objects type <type>
+
+Returns all objects of the given type.
+
+=item list objects flag <flag>
+
+Returns all objects which have the given flag set.
+
+=item list objects owner <acl name>
+
+Returns all objects owned by the given ACL name.
+
+=item list objects acl <acl name>
+
+Returns all objects for which the given ACL name has any permissions.
+This includes those objects owned by the ACL, but also those for which the
+ACL has get permissions, for example.
+
+=back
+
+The currently supported ACL search types are:
+
+=over 4
+
+=item list acls empty
+
+Returns all ACLs which have no entries, generally so that abandoned ACLs
+can be destroyed.
+
+=item list acls entry <schema> <identifier>
+
+Returns all ACLs containing an entry with given schema and identifier.
+The schema is used for an exact search, while the identifier given will
+match any identifier containing that text, for flexibility.
+
+=back
+
=item register (object | verifier) <type> <class>
Registers an implementation of a wallet object or ACL verifier in the
@@ -169,14 +232,35 @@ default as part of database initialization, so this command is used
primarily to register local implementations of additional object types or
ACL schemes.
+=item report <type> [ <arg> ... ]
+
+Runs a wallet report. The currently supported report types are:
+
+=over 4
+
+=item report owners <type-pattern> <name-pattern>
+
+Returns a list of all ACL lines in owner ACLs for all objects matching
+both <type-pattern> and <name-pattern>. These can be the type or name of
+objects or they can be patterns using C<%> as the wildcard character
+following the normal rules of SQL patterns.
+
+The output will be one line per ACL line in the form:
+
+ <scheme> <identifier>
+
+with duplicates suppressed.
+
+=back
+
=back
=head1 SEE ALSO
Wallet::Admin(3), Wallet::Config(3), wallet-backend(8)
-This program is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This program is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/server/wallet-admin.8 b/server/wallet-admin.8
new file mode 100644
index 0000000..4d262dc
--- /dev/null
+++ b/server/wallet-admin.8
@@ -0,0 +1,269 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "WALLET-ADMIN 8"
+.TH WALLET-ADMIN 8 "2010-02-20" "0.10" "wallet"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+wallet\-admin \- Wallet server administrative commands
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBwallet-admin\fR \fIcommand\fR [\fIargs\fR ...]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBwallet-admin\fR provides a command-line interface for performing
+administrative actions for the wallet system, such as setting up a new
+database or running reports. It is intended to be run on the wallet
+server as a user with access to the wallet database and configuration.
+.PP
+This program is a fairly thin wrapper around Wallet::Admin that translates
+command strings into method calls and returns the results.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+\&\fBwallet-admin\fR takes no traditional options.
+.SH "COMMANDS"
+.IX Header "COMMANDS"
+.IP "destroy" 4
+.IX Item "destroy"
+Deletes all data in the wallet database and drops all of the
+wallet-created tables, restoring the database to its state prior to an
+\&\f(CW\*(C`initialize\*(C'\fR command. Since this command is destructive and cannot be
+easily recovered from, \fBwallet-admin\fR will prompt first to be sure the
+user intends to do this.
+.IP "initialize <principal>" 4
+.IX Item "initialize <principal>"
+Given an empty database, initializes it for use with the wallet server by
+creating the necessary tables and initial metadata. Also creates an \s-1ACL\s0
+with the name \s-1ADMIN\s0, used for administrative privileges to the wallet
+system, and adds an \s-1ACL\s0 entry to it with a scheme of \f(CW\*(C`krb5\*(C'\fR and an
+instance of <principal>. This bootstraps the authentication system and
+allows that user to make further changes to the \s-1ADMIN\s0 \s-1ACL\s0 and the rest of
+the wallet database. \f(CW\*(C`initialize\*(C'\fR uses \f(CW\*(C`localhost\*(C'\fR as the hostname and
+<principal> as the user when logging the history of the \s-1ADMIN\s0 \s-1ACL\s0 creation
+and for any subsequent actions required to initialize the database.
+.Sp
+Before running \f(CW\*(C`initialize\*(C'\fR, the wallet system has to be configured. See
+\&\fIWallet::Config\fR\|(3) for more details. Depending on the database backend
+used, the database may also have to be created in advance.
+.IP "list (acls | objects) [ <searchtype> [ <arg> ... ] ]" 4
+.IX Item "list (acls | objects) [ <searchtype> [ <arg> ... ] ]"
+Returns a list of ACLs or objects in the database. ACLs will be listed
+in the form:
+.Sp
+.Vb 1
+\& <name> (ACL ID: <id>)
+.Ve
+.Sp
+where <name> is the human-readable name and <id> is the numeric \s-1ID\s0. The
+numeric \s-1ID\s0 is what's used internally by the wallet system. Objects will
+be listed in the form:
+.Sp
+.Vb 1
+\& <type> <name>
+.Ve
+.Sp
+In both cases, there will be one line per \s-1ACL\s0 or object.
+.Sp
+If no search type is given, all the ACLs or objects in the database will
+be returned. If a search type (and possible search arguments) are given,
+then the ACLs or objects will be limited to those that match the search.
+.Sp
+The currently supported object search types are:
+.RS 4
+.IP "list objects type <type>" 4
+.IX Item "list objects type <type>"
+Returns all objects of the given type.
+.IP "list objects flag <flag>" 4
+.IX Item "list objects flag <flag>"
+Returns all objects which have the given flag set.
+.IP "list objects owner <acl name>" 4
+.IX Item "list objects owner <acl name>"
+Returns all objects owned by the given \s-1ACL\s0 name.
+.IP "list objects acl <acl name>" 4
+.IX Item "list objects acl <acl name>"
+Returns all objects for which the given \s-1ACL\s0 name has any permissions.
+This includes those objects owned by the \s-1ACL\s0, but also those for which the
+\&\s-1ACL\s0 has get permissions, for example.
+.RE
+.RS 4
+.Sp
+The currently supported \s-1ACL\s0 search types are:
+.IP "list acls empty" 4
+.IX Item "list acls empty"
+Returns all ACLs which have no entries, generally so that abandoned ACLs
+can be destroyed.
+.IP "list acls entry <schema> <identifier>" 4
+.IX Item "list acls entry <schema> <identifier>"
+Returns all ACLs containing an entry with given schema and identifier.
+The schema is used for an exact search, while the identifier given will
+match any identifier containing that text, for flexibility.
+.RE
+.RS 4
+.RE
+.IP "register (object | verifier) <type> <class>" 4
+.IX Item "register (object | verifier) <type> <class>"
+Registers an implementation of a wallet object or \s-1ACL\s0 verifier in the
+wallet database. The Perl class <class> is registered as the
+implementation of an object of type <type> or an \s-1ACL\s0 verifier of scheme
+<type>, allowing creation of objects with that type or \s-1ACL\s0 lines with that
+scheme.
+.Sp
+All object and \s-1ACL\s0 implementations that come with wallet are registered by
+default as part of database initialization, so this command is used
+primarily to register local implementations of additional object types or
+\&\s-1ACL\s0 schemes.
+.IP "report <type> [ <arg> ... ]" 4
+.IX Item "report <type> [ <arg> ... ]"
+Runs a wallet report. The currently supported report types are:
+.RS 4
+.IP "report owners <type\-pattern> <name\-pattern>" 4
+.IX Item "report owners <type-pattern> <name-pattern>"
+Returns a list of all \s-1ACL\s0 lines in owner ACLs for all objects matching
+both <type\-pattern> and <name\-pattern>. These can be the type or name of
+objects or they can be patterns using \f(CW\*(C`%\*(C'\fR as the wildcard character
+following the normal rules of \s-1SQL\s0 patterns.
+.Sp
+The output will be one line per \s-1ACL\s0 line in the form:
+.Sp
+.Vb 1
+\& <scheme> <identifier>
+.Ve
+.Sp
+with duplicates suppressed.
+.RE
+.RS 4
+.RE
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIWallet::Admin\fR\|(3), \fIWallet::Config\fR\|(3), \fIwallet\-backend\fR\|(8)
+.PP
+This program is part of the wallet system. The current version is
+available from <http://www.eyrie.org/~eagle/software/wallet/>.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Russ Allbery <rra@stanford.edu>
diff --git a/server/wallet-backend b/server/wallet-backend
index 74e0eb0..0a611db 100755
--- a/server/wallet-backend
+++ b/server/wallet-backend
@@ -1,10 +1,9 @@
#!/usr/bin/perl
-our $ID = q$Id$;
#
# wallet-backend -- Wallet server for storing and retrieving secure data.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -285,7 +284,11 @@ sub command {
failure ($server->error, @_);
}
} elsif ($command eq 'store') {
- check_args (3, 3, [3], @args);
+ check_args (2, 3, [3], @args);
+ if (@args == 2) {
+ local $/;
+ $args[2] = <STDIN>;
+ }
splice (@_, 3);
$server->store (@args) or failure ($server->error, @_);
} else {
@@ -312,6 +315,11 @@ __END__
# The commands section of this document is duplicated from the documentation
# for wallet and should be kept in sync.
+=for stopwords
+wallet-backend backend backend-specific remctld ACL acl timestamp getacl
+setacl metadata keytab keytabs enctypes enctype ktadd KDC Allbery
+autocreate
+
=head1 NAME
wallet-backend - Wallet server for storing and retrieving secure data
@@ -322,20 +330,22 @@ B<wallet-backend> [B<-q>] I<command> [I<args> ...]
=head1 DESCRIPTION
-B<wallet-backend> implements the interface between B<remctld> and the wallet
-system. It is written to run under B<remctld> and expects the authenticated
-identity of the remote user in the REMOTE_USER environment variable. It
-uses REMOTE_HOST or REMOTE_ADDR if REMOTE_HOST isn't set for additional
-trace information. It accepts the command from B<remctld> on the command
-line, creates a Wallet::Server object, and calls the appropriate methods.
-
-This program is a fairly thin wrapper around Wallet::Server that translates
-command strings into method calls and returns the results. It does check
-all arguments except for the <data> argument to the store command and
-rejects any argument not matching C<^[\w_/.-]+\z>; in other words, only
-alphanumerics, underscore (C<_>), slash (C</>), period (C<.>), and hyphen
-(C<->) are permitted in arguments. This provides some additional security
-over and above the checking already done by the rest of the wallet code.
+B<wallet-backend> implements the interface between B<remctld> and the
+wallet system. It is written to run under B<remctld> and expects the
+authenticated identity of the remote user in the REMOTE_USER environment
+variable. It uses REMOTE_HOST or REMOTE_ADDR if REMOTE_HOST isn't set for
+additional trace information. It accepts the command from B<remctld> on
+the command line, creates a Wallet::Server object, and calls the
+appropriate methods.
+
+This program is a fairly thin wrapper around Wallet::Server that
+translates command strings into method calls and returns the results. It
+does check all arguments except for the <data> argument to the store
+command and rejects any argument not matching C<^[\w_/.-]+\z>; in other
+words, only alphanumerics, underscore (C<_>), slash (C</>), period (C<.>),
+and hyphen (C<->) are permitted in arguments. This provides some
+additional security over and above the checking already done by the rest
+of the wallet code.
=head1 OPTIONS
@@ -401,7 +411,7 @@ Display the history of the ACL <id>. Each change to the ACL (not
including changes to the name of the ACL) will be represented by two
lines. The first line will have a timestamp of the change followed by a
description of the change, and the second line will give the user who made
-the change and the host from which the change was mde.
+the change and the host from which the change was made.
=item acl remove <id> <scheme> <identifier>
@@ -448,8 +458,8 @@ The expiration will be displayed in seconds since epoch.
If <date> is given, sets the expiration on the object identified by <type>
and <name> to <date> and (if given) <time>. <date> must be in the format
-C<YYYY-MM-DD> and <time> in the format C<HH:MM:SS>. If <date> is the empty
-string, clears the expiration of the object.
+C<YYYY-MM-DD> and <time> in the format C<HH:MM:SS>. If <date> is the
+empty string, clears the expiration of the object.
Currently, the expiration of an object is not used.
@@ -461,16 +471,16 @@ Clears the flag <flag> on the object identified by <type> and <name>.
Sets the flag <flag> on the object identified by <type> and <name>.
Recognized flags are C<locked>, which prevents all further actions on that
-object until the flag is cleared, and C<unchanging>, which tells the object
-backend to not generate new data on get but instead return the same data as
-previously returned. The C<unchanging> flag is not meaningful for objects
-that do not generate new data on the fly.
+object until the flag is cleared, and C<unchanging>, which tells the
+object backend to not generate new data on get but instead return the same
+data as previously returned. The C<unchanging> flag is not meaningful for
+objects that do not generate new data on the fly.
=item get <type> <name>
-Prints to standard output the data associated with the object identified by
-<type> and <name>. This may trigger generation of new data and invalidate
-old data for that object depending on the object type.
+Prints to standard output the data associated with the object identified
+by <type> and <name>. This may trigger generation of new data and
+invalidate old data for that object depending on the object type.
=item getacl <type> <name> <acl>
@@ -486,17 +496,17 @@ or setting it.
Prints the object attribute <attr> for the object identified by <type> and
<name>. Attributes are used to store backend-specific information for a
particular object type, and <attr> must be an attribute type known to the
-underlying object implementation. The attribute values, if any, are printed
-one per line. If the attribute is not set on this object, nothing is
-printed.
+underlying object implementation. The attribute values, if any, are
+printed one per line. If the attribute is not set on this object, nothing
+is printed.
=item history <type> <name>
-Displays the history for the object identified by <type> and <name>.
-This human-readable output will have two lines for each action that
-changes the object, plus for any get action. The first line has the
-timestamp of the action and the action, and the second line gives the user
-who performed the action and the host from which they performed it.
+Displays the history for the object identified by <type> and <name>. This
+human-readable output will have two lines for each action that changes the
+object, plus for any get action. The first line has the timestamp of the
+action and the action, and the second line gives the user who performed
+the action and the host from which they performed it.
=item owner <type> <name> [<owner>]
@@ -530,15 +540,11 @@ name, the owner, any specific ACLs set on the object, the expiration if
any, and the user, remote host, and time when the object was created, last
stored, and last downloaded.
-=item store <type> <name> <data>
+=item store <type> <name> [<data>]
Stores <data> for the object identified by <type> and <name> for later
-retrieval with C<get>. Not all object types support this.
-
-Currently, <data> is limited to not containing nul characters and may
-therefore not be binary data, and is limited by the maximum command line
-length of the operating system of the wallet server. These restrictions
-will be lifted in the future.
+retrieval with C<get>. Not all object types support this. If <data> is
+not given as an argument, it will be read from standard input.
=back
@@ -559,47 +565,27 @@ Keytab objects support the following attributes:
Restricts the generated keytab to a specific set of encryption types. The
values of this attribute must be enctype strings recognized by Kerberos
-(strings like C<aes256-cts> or C<des-cbc-crc>). Note that the salt should
-not be included; since the salt is irrelevant for keytab keys, it will
-always be set to C<normal> by the wallet.
+(strings like C<aes256-cts-hmac-sha1-96> or C<des-cbc-crc>). Note that
+the salt should not be included; since the salt is irrelevant for keytab
+keys, it will always be set to C<normal> by the wallet.
-If this attribute is set, the specified enctype list will be passed to ktadd
-when get() is called for that keytab. If it is not set, the default set in
-the KDC will be used.
+If this attribute is set, the specified enctype list will be passed to
+ktadd when get() is called for that keytab. If it is not set, the default
+set in the KDC will be used.
This attribute is ignored if the C<unchanging> flag is set on a keytab.
Keytabs retrieved with C<unchanging> set will contain all keys present in
the KDC for that Kerberos principal and therefore may contain different
enctypes than those requested by this attribute.
-=item sync
-
-Sets the external systems to which the key of a given principal is
-synchronized. The only supported value for this attribute is C<kaserver>,
-which says to synchronize the key with an AFS Kerberos v4 kaserver.
-
-If this attribute is set on a keytab, whenever the C<get> command is run for
-that keytab, the DES key will be extracted from that keytab and set in the
-configured AFS kaserver. The Kerberos v4 principal name will be the same as
-the Kerberos v5 principal name except that the components are separated by
-C<.> instead of C</>; the second component is truncated after the first C<.>
-if the first component is one of C<host>, C<ident>, C<imap>, C<pop>, or
-C<smtp>; and the first component is C<rcmd> if the Kerberos v5 principal
-component is C<host>. The principal name must not contain more than two
-components.
-
-If this attribute is set, calling C<destroy> will also destroy the
-principal from the AFS kaserver, with a principal mapping determined as
-above.
-
=back
=head1 SEE ALSO
Wallet::Server(3), remctld(8)
-This program is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This program is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/server/wallet-backend.8 b/server/wallet-backend.8
new file mode 100644
index 0000000..4369ba4
--- /dev/null
+++ b/server/wallet-backend.8
@@ -0,0 +1,357 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "WALLET-BACKEND 8"
+.TH WALLET-BACKEND 8 "2010-02-20" "0.10" "wallet"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+wallet\-backend \- Wallet server for storing and retrieving secure data
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBwallet-backend\fR [\fB\-q\fR] \fIcommand\fR [\fIargs\fR ...]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBwallet-backend\fR implements the interface between \fBremctld\fR and the
+wallet system. It is written to run under \fBremctld\fR and expects the
+authenticated identity of the remote user in the \s-1REMOTE_USER\s0 environment
+variable. It uses \s-1REMOTE_HOST\s0 or \s-1REMOTE_ADDR\s0 if \s-1REMOTE_HOST\s0 isn't set for
+additional trace information. It accepts the command from \fBremctld\fR on
+the command line, creates a Wallet::Server object, and calls the
+appropriate methods.
+.PP
+This program is a fairly thin wrapper around Wallet::Server that
+translates command strings into method calls and returns the results. It
+does check all arguments except for the <data> argument to the store
+command and rejects any argument not matching \f(CW\*(C`^[\ew_/.\-]+\ez\*(C'\fR; in other
+words, only alphanumerics, underscore (\f(CW\*(C`_\*(C'\fR), slash (\f(CW\*(C`/\*(C'\fR), period (\f(CW\*(C`.\*(C'\fR),
+and hyphen (\f(CW\*(C`\-\*(C'\fR) are permitted in arguments. This provides some
+additional security over and above the checking already done by the rest
+of the wallet code.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\fB\-\-quiet\fR, \fB\-q\fR" 4
+.IX Item "--quiet, -q"
+If this option is given, \fBwallet-backend\fR will not log its actions to
+syslog.
+.SH "COMMANDS"
+.IX Header "COMMANDS"
+Most commands are only available to wallet administrators (users on the
+\&\f(CW\*(C`ADMIN\*(C'\fR \s-1ACL\s0). The exceptions are \f(CW\*(C`autocreate\*(C'\fR, \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR,
+\&\f(CW\*(C`show\*(C'\fR, \f(CW\*(C`destroy\*(C'\fR, \f(CW\*(C`flag clear\*(C'\fR, \f(CW\*(C`flag set\*(C'\fR, \f(CW\*(C`getattr\*(C'\fR, \f(CW\*(C`setattr\*(C'\fR,
+and \f(CW\*(C`history\*(C'\fR. All of those commands have their own ACLs except
+\&\f(CW\*(C`getattr\*(C'\fR and \f(CW\*(C`history\*(C'\fR, which use the \f(CW\*(C`show\*(C'\fR \s-1ACL\s0, and \f(CW\*(C`setattr\*(C'\fR,
+which uses the \f(CW\*(C`store\*(C'\fR \s-1ACL\s0. If the appropriate \s-1ACL\s0 is set, it alone is
+checked to see if the user has access. Otherwise, \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR,
+\&\f(CW\*(C`show\*(C'\fR, \f(CW\*(C`getattr\*(C'\fR, \f(CW\*(C`setattr\*(C'\fR, and \f(CW\*(C`history\*(C'\fR access is permitted if the
+user is authorized by the owner \s-1ACL\s0 of the object. \f(CW\*(C`autocreate\*(C'\fR is
+permitted if the user is listed in the default \s-1ACL\s0 for an object for that
+name.
+.PP
+Administrators can run any command on any object or \s-1ACL\s0 except for \f(CW\*(C`get\*(C'\fR
+and \f(CW\*(C`store\*(C'\fR. For \f(CW\*(C`get\*(C'\fR and \f(CW\*(C`store\*(C'\fR, they must still be authorized by
+either the appropriate specific \s-1ACL\s0 or the owner \s-1ACL\s0.
+.PP
+If the locked flag is set on an object, no commands can be run on that
+object that change data except the \f(CW\*(C`flags\*(C'\fR commands, nor can the \f(CW\*(C`get\*(C'\fR
+command be used on that object. \f(CW\*(C`show\*(C'\fR, \f(CW\*(C`history\*(C'\fR, \f(CW\*(C`getacl\*(C'\fR,
+\&\f(CW\*(C`getattr\*(C'\fR, and \f(CW\*(C`owner\*(C'\fR or \f(CW\*(C`expires\*(C'\fR without an argument can still be
+used on that object.
+.PP
+For more information on attributes, see \s-1ATTRIBUTES\s0.
+.IP "acl add <id> <scheme> <identifier>" 4
+.IX Item "acl add <id> <scheme> <identifier>"
+Adds an entry with <scheme> and <identifier> to the \s-1ACL\s0 <id>. <id> may be
+either the name of an \s-1ACL\s0 or its numeric identifier.
+.IP "acl create <name>" 4
+.IX Item "acl create <name>"
+Create a new, empty \s-1ACL\s0 with name <name>. When setting an \s-1ACL\s0 on an
+object with a set of entries that don't match an existing \s-1ACL\s0, first
+create a new \s-1ACL\s0 with \f(CW\*(C`acl create\*(C'\fR, add the appropriate entries to it
+with \f(CW\*(C`acl add\*(C'\fR, and then set the \s-1ACL\s0 on an object with the \f(CW\*(C`owner\*(C'\fR or
+\&\f(CW\*(C`setacl\*(C'\fR commands.
+.IP "acl destroy <id>" 4
+.IX Item "acl destroy <id>"
+Destroy the \s-1ACL\s0 <id>. This \s-1ACL\s0 must no longer be referenced by any object
+or the \s-1ACL\s0 destruction will fail. The special \s-1ACL\s0 named \f(CW\*(C`ADMIN\*(C'\fR cannot
+be destroyed.
+.IP "acl history <id>" 4
+.IX Item "acl history <id>"
+Display the history of the \s-1ACL\s0 <id>. Each change to the \s-1ACL\s0 (not
+including changes to the name of the \s-1ACL\s0) will be represented by two
+lines. The first line will have a timestamp of the change followed by a
+description of the change, and the second line will give the user who made
+the change and the host from which the change was made.
+.IP "acl remove <id> <scheme> <identifier>" 4
+.IX Item "acl remove <id> <scheme> <identifier>"
+Remove the entry with <scheme> and <identifier> from the \s-1ACL\s0 <id>. <id>
+may be either the name of an \s-1ACL\s0 or its numeric identifier. The last
+entry in the special \s-1ACL\s0 \f(CW\*(C`ADMIN\*(C'\fR cannot be removed to protect against
+accidental lockout, but administrators can remove themselves from the
+\&\f(CW\*(C`ADMIN\*(C'\fR \s-1ACL\s0 and can leave only a non-functioning entry on the \s-1ACL\s0. Use
+caution when removing entries from the \f(CW\*(C`ADMIN\*(C'\fR \s-1ACL\s0.
+.IP "acl show <id>" 4
+.IX Item "acl show <id>"
+Display the name, numeric \s-1ID\s0, and entries of the \s-1ACL\s0 <id>.
+.IP "autocreate <type> <name>" 4
+.IX Item "autocreate <type> <name>"
+Create a new object of type <type> with name <name>. The user must be
+listed in the default \s-1ACL\s0 for an object with that type and name, and the
+object will be created with that default \s-1ACL\s0 set as the object owner.
+.IP "check <type> <name>" 4
+.IX Item "check <type> <name>"
+Check whether an object of type <type> and name <name> already exists. If
+it does, prints \f(CW\*(C`yes\*(C'\fR; if not, prints \f(CW\*(C`no\*(C'\fR.
+.IP "create <type> <name>" 4
+.IX Item "create <type> <name>"
+Create a new object of type <type> with name <name>. With some backends,
+this will trigger creation of an entry in an external system as well.
+The new object will have no ACLs and no owner set, so usually the
+administrator will want to then set an owner with \f(CW\*(C`owner\*(C'\fR so that the
+object will be usable.
+.IP "destroy <type> <name>" 4
+.IX Item "destroy <type> <name>"
+Destroy the object identified by <type> and <name>. With some backends,
+this will trigger destruction of an object in an external system as well.
+.IP "expires <type> <name> [<date> [<time>]]" 4
+.IX Item "expires <type> <name> [<date> [<time>]]"
+If <date> is not given, displays the current expiration of the object
+identified by <type> and <name>, or \f(CW\*(C`No expiration set\*(C'\fR if none is set.
+The expiration will be displayed in seconds since epoch.
+.Sp
+If <date> is given, sets the expiration on the object identified by <type>
+and <name> to <date> and (if given) <time>. <date> must be in the format
+\&\f(CW\*(C`YYYY\-MM\-DD\*(C'\fR and <time> in the format \f(CW\*(C`HH:MM:SS\*(C'\fR. If <date> is the
+empty string, clears the expiration of the object.
+.Sp
+Currently, the expiration of an object is not used.
+.IP "flag clear <type> <name> <flag>" 4
+.IX Item "flag clear <type> <name> <flag>"
+Clears the flag <flag> on the object identified by <type> and <name>.
+.IP "flag set <type> <name> <flag>" 4
+.IX Item "flag set <type> <name> <flag>"
+Sets the flag <flag> on the object identified by <type> and <name>.
+Recognized flags are \f(CW\*(C`locked\*(C'\fR, which prevents all further actions on that
+object until the flag is cleared, and \f(CW\*(C`unchanging\*(C'\fR, which tells the
+object backend to not generate new data on get but instead return the same
+data as previously returned. The \f(CW\*(C`unchanging\*(C'\fR flag is not meaningful for
+objects that do not generate new data on the fly.
+.IP "get <type> <name>" 4
+.IX Item "get <type> <name>"
+Prints to standard output the data associated with the object identified
+by <type> and <name>. This may trigger generation of new data and
+invalidate old data for that object depending on the object type.
+.IP "getacl <type> <name> <acl>" 4
+.IX Item "getacl <type> <name> <acl>"
+Prints the \s-1ACL\s0 <acl>, which must be one of \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, \f(CW\*(C`show\*(C'\fR,
+\&\f(CW\*(C`destroy\*(C'\fR, or \f(CW\*(C`flags\*(C'\fR, for the object identified by <type> and <name>.
+Prints \f(CW\*(C`No ACL set\*(C'\fR if that \s-1ACL\s0 isn't set on that object. Remember that
+if the \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, or \f(CW\*(C`show\*(C'\fR ACLs aren't set, authorization falls
+back to checking the owner \s-1ACL\s0. See the \f(CW\*(C`owner\*(C'\fR command for displaying
+or setting it.
+.IP "getattr <type> <name> <attr>" 4
+.IX Item "getattr <type> <name> <attr>"
+Prints the object attribute <attr> for the object identified by <type> and
+<name>. Attributes are used to store backend-specific information for a
+particular object type, and <attr> must be an attribute type known to the
+underlying object implementation. The attribute values, if any, are
+printed one per line. If the attribute is not set on this object, nothing
+is printed.
+.IP "history <type> <name>" 4
+.IX Item "history <type> <name>"
+Displays the history for the object identified by <type> and <name>. This
+human-readable output will have two lines for each action that changes the
+object, plus for any get action. The first line has the timestamp of the
+action and the action, and the second line gives the user who performed
+the action and the host from which they performed it.
+.IP "owner <type> <name> [<owner>]" 4
+.IX Item "owner <type> <name> [<owner>]"
+If <owner> is not given, displays the current owner \s-1ACL\s0 of the object
+identified by <type> and <name>, or \f(CW\*(C`No owner set\*(C'\fR if none is set. The
+result will be the name of an \s-1ACL\s0.
+.Sp
+If <owner> is given, sets the owner of the object identified by <type> and
+<name> to <owner>. If <owner> is the empty string, clears the owner of
+the object.
+.IP "setacl <type> <name> <acl> <id>" 4
+.IX Item "setacl <type> <name> <acl> <id>"
+Sets the \s-1ACL\s0 <acl>, which must be one of \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, \f(CW\*(C`show\*(C'\fR,
+\&\f(CW\*(C`destroy\*(C'\fR, or \f(CW\*(C`flags\*(C'\fR, to <id> on the object identified by <type> and
+<name>. If <id> is the empty string, clears that \s-1ACL\s0 on the object.
+.IP "setattr <type> <name> <attr> <value> [<value> ...]" 4
+.IX Item "setattr <type> <name> <attr> <value> [<value> ...]"
+Sets the object attribute <attr> for the object identified by <type> and
+<name>. Attributes are used to store backend-specific information for a
+particular object type, and <attr> must be an attribute type known to the
+underlying object implementation. To clear the attribute for this object,
+pass in a <value> of the empty string (\f(CW\*(Aq\*(Aq\fR).
+.IP "show <type> <name>" 4
+.IX Item "show <type> <name>"
+Displays the current object metadata for the object identified by <type>
+and <name>. This human-readable output will show the object type and
+name, the owner, any specific ACLs set on the object, the expiration if
+any, and the user, remote host, and time when the object was created, last
+stored, and last downloaded.
+.IP "store <type> <name> [<data>]" 4
+.IX Item "store <type> <name> [<data>]"
+Stores <data> for the object identified by <type> and <name> for later
+retrieval with \f(CW\*(C`get\*(C'\fR. Not all object types support this. If <data> is
+not given as an argument, it will be read from standard input.
+.SH "ATTRIBUTES"
+.IX Header "ATTRIBUTES"
+Object attributes store additional properties and configuration
+information for objects stored in the wallet. They are displayed as part
+of the object data with \f(CW\*(C`show\*(C'\fR, retrieved with \f(CW\*(C`getattr\*(C'\fR, and set with
+\&\f(CW\*(C`setattr\*(C'\fR.
+.SS "Keytab Attributes"
+.IX Subsection "Keytab Attributes"
+Keytab objects support the following attributes:
+.IP "enctypes" 4
+.IX Item "enctypes"
+Restricts the generated keytab to a specific set of encryption types. The
+values of this attribute must be enctype strings recognized by Kerberos
+(strings like \f(CW\*(C`aes256\-cts\-hmac\-sha1\-96\*(C'\fR or \f(CW\*(C`des\-cbc\-crc\*(C'\fR). Note that
+the salt should not be included; since the salt is irrelevant for keytab
+keys, it will always be set to \f(CW\*(C`normal\*(C'\fR by the wallet.
+.Sp
+If this attribute is set, the specified enctype list will be passed to
+ktadd when \fIget()\fR is called for that keytab. If it is not set, the default
+set in the \s-1KDC\s0 will be used.
+.Sp
+This attribute is ignored if the \f(CW\*(C`unchanging\*(C'\fR flag is set on a keytab.
+Keytabs retrieved with \f(CW\*(C`unchanging\*(C'\fR set will contain all keys present in
+the \s-1KDC\s0 for that Kerberos principal and therefore may contain different
+enctypes than those requested by this attribute.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIWallet::Server\fR\|(3), \fIremctld\fR\|(8)
+.PP
+This program is part of the wallet system. The current version is
+available from <http://www.eyrie.org/~eagle/software/wallet/>.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Russ Allbery <rra@stanford.edu>
diff --git a/server/wallet-report b/server/wallet-report
new file mode 100755
index 0000000..a6b3b8d
--- /dev/null
+++ b/server/wallet-report
@@ -0,0 +1,203 @@
+#!/usr/bin/perl -w
+#
+# wallet-report -- Wallet server reporting interface.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+##############################################################################
+# Declarations and site configuration
+##############################################################################
+
+use strict;
+use Wallet::Report;
+
+##############################################################################
+# Implementation
+##############################################################################
+
+# Parse and execute a command. We wrap this in a subroutine call for easier
+# testing.
+sub command {
+ die "Usage: wallet-report <command> [<args> ...]\n" unless @_;
+ my $report = Wallet::Report->new;
+
+ # Parse command-line options and dispatch to the appropriate calls.
+ my ($command, @args) = @_;
+ if ($command eq 'acls') {
+ die "too many arguments to acls\n" if @args > 3;
+ my @acls = $report->acls (@args);
+ if (!@acls and $report->error) {
+ die $report->error, "\n";
+ }
+ for my $acl (sort { $$a[1] cmp $$b[1] } @acls) {
+ print "$$acl[1] (ACL ID: $$acl[0])\n";
+ }
+ } elsif ($command eq 'objects') {
+ die "too many arguments to objects\n" if @args > 2;
+ my @objects = $report->objects (@args);
+ if (!@objects and $report->error) {
+ die $report->error, "\n";
+ }
+ for my $object (@objects) {
+ print join (' ', @$object), "\n";
+ }
+ } elsif ($command eq 'owners') {
+ die "too many arguments to owners\n" if @args > 2;
+ die "too few arguments to owners\n" if @args < 2;
+ my @entries = $report->owners (@args);
+ if (!@entries and $report->error) {
+ die $report->error, "\n";
+ }
+ for my $entry (@entries) {
+ print join (' ', @$entry), "\n";
+ }
+ } else {
+ die "unknown command $command\n";
+ }
+}
+command (@ARGV);
+__END__
+
+##############################################################################
+# Documentation
+##############################################################################
+
+=head1 NAME
+
+wallet-report - Wallet server reporting interface
+
+=for stopwords
+metadata ACL hostname backend acl acls wildcard SQL Allbery remctl
+
+=head1 SYNOPSIS
+
+B<wallet-report> I<type> [I<args> ...]
+
+=head1 DESCRIPTION
+
+B<wallet-report> provides a command-line interface for running reports on
+the wallet database. It is intended to be run on the wallet server as a
+user with access to the wallet database and configuration, but can also be
+made available via remctl to users who should have reporting privileges.
+
+This program is a fairly thin wrapper around Wallet::Report that
+translates command strings into method calls and returns the results.
+
+=head1 OPTIONS
+
+B<wallet-report> takes no traditional options.
+
+=head1 COMMANDS
+
+=over 4
+
+=item acls
+
+=item acls empty
+
+=item acls entry <scheme> <identifier>
+
+Returns a list of ACLs in the database. ACLs will be listed in the form:
+
+ <name> (ACL ID: <id>)
+
+where <name> is the human-readable name and <id> is the numeric ID. The
+numeric ID is what's used internally by the wallet system. There will be
+one line per ACL.
+
+If no search type is given, all the ACLs in the database will be returned.
+If a search type (and possible search arguments) are given, then the ACLs
+will be limited to those that match the search.
+
+The currently supported ACL search types are:
+
+=over 4
+
+=item acls empty
+
+Returns all ACLs which have no entries, generally so that abandoned ACLs
+can be destroyed.
+
+=item acls entry <scheme> <identifier>
+
+Returns all ACLs containing an entry with given scheme and identifier.
+The scheme must be an exact match, but the <identifier> string will match
+any identifier containing that string.
+
+=back
+
+=item objects
+
+=item objects acl <acl>
+
+=item objects flag <flag>
+
+=item objects owner <owner>
+
+=item objects type <type>
+
+Returns a list of objects in the database. Objects will be listed in the
+form:
+
+ <type> <name>
+
+There will be one line per object.
+
+If no search type is given, all objects in the database will be returned.
+If a search type (and possible search arguments) are given, the objects
+will be limited to those that match the search.
+
+The currently supported object search types are:
+
+=over 4
+
+=item list objects acl <acl>
+
+Returns all objects for which the given ACL name or ID has any
+permissions. This includes those objects owned by the ACL as well as
+those where that ACL has any other, more limited permissions.
+
+=item list objects flag <flag>
+
+Returns all objects which have the given flag set.
+
+=item list objects owner <acl>
+
+Returns all objects owned by the given ACL name or ID.
+
+=item list objects type <type>
+
+Returns all objects of the given type.
+
+=back
+
+=item owners <type-pattern> <name-pattern>
+
+Returns a list of all ACL entries in owner ACLs for all objects matching
+both <type-pattern> and <name-pattern>. These can be the type or name of
+objects or they can be patterns using C<%> as the wildcard character
+following the normal rules of SQL patterns.
+
+The output will be one line per ACL line in the form:
+
+ <scheme> <identifier>
+
+with duplicates suppressed.
+
+=back
+
+=head1 SEE ALSO
+
+Wallet::Config(3), Wallet::Report(3), wallet-backend(8)
+
+This program is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
+
+=head1 AUTHOR
+
+Russ Allbery <rra@stanford.edu>
+
+=cut
diff --git a/server/wallet-report.8 b/server/wallet-report.8
new file mode 100644
index 0000000..147617a
--- /dev/null
+++ b/server/wallet-report.8
@@ -0,0 +1,253 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "WALLET-REPORT 8"
+.TH WALLET-REPORT 8 "2010-02-20" "0.10" "wallet"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+wallet\-report \- Wallet server reporting interface
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBwallet-report\fR \fItype\fR [\fIargs\fR ...]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBwallet-report\fR provides a command-line interface for running reports on
+the wallet database. It is intended to be run on the wallet server as a
+user with access to the wallet database and configuration, but can also be
+made available via remctl to users who should have reporting privileges.
+.PP
+This program is a fairly thin wrapper around Wallet::Report that
+translates command strings into method calls and returns the results.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+\&\fBwallet-report\fR takes no traditional options.
+.SH "COMMANDS"
+.IX Header "COMMANDS"
+.IP "acls" 4
+.IX Item "acls"
+.PD 0
+.IP "acls empty" 4
+.IX Item "acls empty"
+.IP "acls entry <scheme> <identifier>" 4
+.IX Item "acls entry <scheme> <identifier>"
+.PD
+Returns a list of ACLs in the database. ACLs will be listed in the form:
+.Sp
+.Vb 1
+\& <name> (ACL ID: <id>)
+.Ve
+.Sp
+where <name> is the human-readable name and <id> is the numeric \s-1ID\s0. The
+numeric \s-1ID\s0 is what's used internally by the wallet system. There will be
+one line per \s-1ACL\s0.
+.Sp
+If no search type is given, all the ACLs in the database will be returned.
+If a search type (and possible search arguments) are given, then the ACLs
+will be limited to those that match the search.
+.Sp
+The currently supported \s-1ACL\s0 search types are:
+.RS 4
+.IP "acls empty" 4
+.IX Item "acls empty"
+Returns all ACLs which have no entries, generally so that abandoned ACLs
+can be destroyed.
+.IP "acls entry <scheme> <identifier>" 4
+.IX Item "acls entry <scheme> <identifier>"
+Returns all ACLs containing an entry with given scheme and identifier.
+The scheme must be an exact match, but the <identifier> string will match
+any identifier containing that string.
+.RE
+.RS 4
+.RE
+.IP "objects" 4
+.IX Item "objects"
+.PD 0
+.IP "objects acl <acl>" 4
+.IX Item "objects acl <acl>"
+.IP "objects flag <flag>" 4
+.IX Item "objects flag <flag>"
+.IP "objects owner <owner>" 4
+.IX Item "objects owner <owner>"
+.IP "objects type <type>" 4
+.IX Item "objects type <type>"
+.PD
+Returns a list of objects in the database. Objects will be listed in the
+form:
+.Sp
+.Vb 1
+\& <type> <name>
+.Ve
+.Sp
+There will be one line per object.
+.Sp
+If no search type is given, all objects in the database will be returned.
+If a search type (and possible search arguments) are given, the objects
+will be limited to those that match the search.
+.Sp
+The currently supported object search types are:
+.RS 4
+.IP "list objects acl <acl>" 4
+.IX Item "list objects acl <acl>"
+Returns all objects for which the given \s-1ACL\s0 name or \s-1ID\s0 has any
+permissions. This includes those objects owned by the \s-1ACL\s0 as well as
+those where that \s-1ACL\s0 has any other, more limited permissions.
+.IP "list objects flag <flag>" 4
+.IX Item "list objects flag <flag>"
+Returns all objects which have the given flag set.
+.IP "list objects owner <acl>" 4
+.IX Item "list objects owner <acl>"
+Returns all objects owned by the given \s-1ACL\s0 name or \s-1ID\s0.
+.IP "list objects type <type>" 4
+.IX Item "list objects type <type>"
+Returns all objects of the given type.
+.RE
+.RS 4
+.RE
+.IP "owners <type\-pattern> <name\-pattern>" 4
+.IX Item "owners <type-pattern> <name-pattern>"
+Returns a list of all \s-1ACL\s0 entries in owner ACLs for all objects matching
+both <type\-pattern> and <name\-pattern>. These can be the type or name of
+objects or they can be patterns using \f(CW\*(C`%\*(C'\fR as the wildcard character
+following the normal rules of \s-1SQL\s0 patterns.
+.Sp
+The output will be one line per \s-1ACL\s0 line in the form:
+.Sp
+.Vb 1
+\& <scheme> <identifier>
+.Ve
+.Sp
+with duplicates suppressed.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIWallet::Config\fR\|(3), \fIWallet::Report\fR\|(3), \fIwallet\-backend\fR\|(8)
+.PP
+This program is part of the wallet system. The current version is
+available from <http://www.eyrie.org/~eagle/software/wallet/>.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Russ Allbery <rra@stanford.edu>