<pre style='margin:0'>
Clemens Lang (neverpanic) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/a2792f4120bbf7fc5b7f771930da83895fd504f1">https://github.com/macports/macports-ports/commit/a2792f4120bbf7fc5b7f771930da83895fd504f1</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit a2792f4120bbf7fc5b7f771930da83895fd504f1
</span>Author: A. Karl Kornel <akkornel@stanford.edu>
AuthorDate: Mon Oct 31 12:42:00 2016 -0700

<span style='display:block; white-space:pre;color:#404040;'>    New port for wallet @1.3
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    wallet is a Kerberos-authenticated file storage & retrieval engine, which has
</span><span style='display:block; white-space:pre;color:#404040;'>    support for automatically generating things like Kerberos keytabs and random
</span><span style='display:block; white-space:pre;color:#404040;'>    passwords. Authentication is via Kerberos, and client-server communication is
</span><span style='display:block; white-space:pre;color:#404040;'>    via remctl. The client is written in C, the server is Perl, and there is also
</span><span style='display:block; white-space:pre;color:#404040;'>    a Perl script that can be placed on Kerberos 5 KDCs to aid in keytab
</span><span style='display:block; white-space:pre;color:#404040;'>    retrieval.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    I am attaching the proposed Portfile and twelve patch files. The patches are
</span><span style='display:block; white-space:pre;color:#404040;'>    needed because wallet's build & install process does not allow setting custom
</span><span style='display:block; white-space:pre;color:#404040;'>    Perl paths. All of the patches have been submitted upstream.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Closes: https://trac.macports.org/ticket/50421
</span>---
 net/wallet/Portfile                                |  245 ++++
 net/wallet/files/patch-Makefile.am.diff            |  118 ++
 net/wallet/files/patch-README.diff                 |   28 +
 net/wallet/files/patch-autogen.diff                |   22 +
 net/wallet/files/patch-configure.ac.diff           |   25 +
 net/wallet/files/patch-perl-Build.PL.diff          |   13 +
 net/wallet/files/patch-portable-system.h.diff      |   15 +
 .../files/patch-rename-server-keytab-backend.diff  |  496 +++++++
 .../files/patch-rename-server-wallet-admin.diff    |  356 +++++
 .../files/patch-rename-server-wallet-backend.diff  | 1396 ++++++++++++++++++++
 .../files/patch-rename-server-wallet-report.diff   |  726 ++++++++++
 net/wallet/files/patch-tests-client-full-t.in.diff |    9 +
 .../files/patch-tests-client-prompt-t.in.diff      |    9 +
 13 files changed, 3458 insertions(+)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/Portfile b/net/wallet/Portfile
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..34e08c5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,245 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PortSystem          1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+PortGroup           perl5 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+perl5.branches      5.24
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+name                wallet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+version             1.3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+revision            0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+categories          net security
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+license             MIT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+maintainers         kornel.us:karl openmaintainer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+description         Kerberos-authenticated secure data management
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+long_description    The wallet is a system for managing secure data, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    authorization rules to retrieve or change that data, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    and audit rules for documenting actions taken on that \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    data.  Objects of various types may be stored in the \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    wallet or generated on request and retrieved by \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    authorized users.  The wallet tracks ACLs, metadata, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    and trace information.  It uses Kerberos \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    authentication.  One of the object types it supports \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    is Kerberos keytabs, making it suitable as a \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    user-accessible front-end to Kerberos kadmind with \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    richer ACL and metadata operations.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+homepage            http://eyrie.org/~eagle/software/wallet/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+platforms           darwin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+master_sites        http://archives.eyrie.org/software/kerberos/ \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    http://archives.eyrie.org/software/ARCHIVE/wallet/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+checksums           rmd160 188b3561fcffe99342fcfb1312b58df3f3d919b5 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    sha256 676d3d6e407509fc9da1dd87d98fadc71920dabfbc4bdeb8cde5e2bc937268b8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Start with the dependencies we know we need
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+depends_lib-append  port:kerberos5 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    port:remctl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Add a dependency on Module::Build
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {${perl5.major} != ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    depends_lib-append     port:p${perl5.major}-module-build
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# wallet 1.3 does not support Perl paths other than /usr/bin/perl, nor does it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# support perl binaries not named "perl".  The perl/Build.PL script is also
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# missing some testing prerequisites.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Since we are patching autoconf and automake files, we need autoreconf.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+patchfiles          patch-autogen.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-configure.ac.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-Makefile.am.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-README.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-perl-Build.PL.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-portable-system.h.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-rename-server-keytab-backend.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-rename-server-wallet-admin.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-rename-server-wallet-backend.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-rename-server-wallet-report.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-tests-client-full-t.in.diff \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-tests-client-prompt-t.in.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+use_autoreconf      yes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Use configure, and pass in the paths to MacPorts kerberos5, remctl, and perl.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.args      --enable-reduced-depends \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    --with-remctl=${prefix} \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    PATH_KRB5_CONFIG=${prefix}/bin/krb5-config \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    PERL=${prefix}/bin/perl${perl5.major} 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Our top-level port installs the Wallet client.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# The Wallet client is just a couple of binaries, plus man pages and docs.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# We override the destroot to just install client stuff.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+destroot {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # First, install common files from the distribution
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    xinstall -d ${destroot}${prefix}/share/doc/wallet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    xinstall -m 644 ${worksrcpath}/LICENSE \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${worksrcpath}/NEWS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${worksrcpath}/README \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${worksrcpath}/TODO \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${destroot}${prefix}/share/doc/wallet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Install the wallet client executables
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # ${destroot}${prefix}/bin already exists
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    xinstall -m 755 ${worksrcpath}/client/wallet \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${worksrcpath}/client/wallet-rekey \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${destroot}${prefix}/bin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Install the wallet client man pages
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    xinstall -d ${destroot}${prefix}/share/man/man1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    xinstall -m 644 ${worksrcpath}/client/wallet.1 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${worksrcpath}/client/wallet-rekey.1 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${destroot}${prefix}/share/man/man1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# The Wallet server is entirely Perl, spawned by the remctl daemon.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# TODO: Patch wallet remctl config files to use ${destroot}${prefix}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+subport wallet-server {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # We can't use perl5.setup because it overrides alot of settings that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # we need.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #perl5.setup           Wallet 1.003
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    long_description-append The wallet server, run by remctld, maintains \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            the database of object metadata and secure \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            objects, and responds to requests from the \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            wallet client.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {${perl5.major} != ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        depends_lib-append      port:p${perl5.major}-datetime \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                port:p${perl5.major}-dbi \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                port:p${perl5.major}-dbix-class \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                port:p${perl5.major}-digest-md5 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                port:p${perl5.major}-sql-translator \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                port:p${perl5.major}-timedate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        depends_build-append    port:p${perl5.major}-crypt-generatepassword \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                port:p${perl5.major}-datetime-format-sqlite
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # TODO: Tests have a Stanford-specific part, and a NetDB-verifier part,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # which need to be disabled.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # test.run      yes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # test.target   check
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # We have our own destroot process, to install just server bits.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    destroot {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # First, install common files from the distribution
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -d ${destroot}${prefix}/share/doc/${subport}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 644 ${worksrcpath}/LICENSE \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${worksrcpath}/NEWS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${worksrcpath}/README \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${worksrcpath}/TODO \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${destroot}${prefix}/share/doc/${subport}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # If installing the server or kdc variants, make common directories
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # These are also created by wallet-kdc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -d ${destroot}${prefix}/etc/remctl/acl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -d ${destroot}${prefix}/etc/remctl/conf.d
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Install a set of starter remctl ACLs and configurations
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # ${destroot}${prefix}/etc/remctl/acl is created above
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 644 ${worksrcpath}/config/wallet-report.acl \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${destroot}${prefix}/etc/remctl/acl/wallet-report
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # ${destroot}${prefix}/etc/remctl/conf.d is created above
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 644 ${worksrcpath}/config/wallet \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${destroot}${prefix}/etc/remctl/conf.d/wallet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Install the wallet server executables
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # ${destroot}${prefix}/sbin already exists
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 755 ${worksrcpath}/server/wallet-admin \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${worksrcpath}/server/wallet-backend \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${worksrcpath}/server/wallet-report \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${destroot}${prefix}/sbin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Install the wallet server man pages
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # ${destroot}${prefix}/share/man/man8 already exists
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 644 ${worksrcpath}/server/wallet-admin.8 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${worksrcpath}/server/wallet-backend.8 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${worksrcpath}/server/wallet-report.8 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${destroot}${prefix}/share/man/man8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Install protocol documentataion
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 644 {*}[glob ${worksrcpath}/docs/*] \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${destroot}${prefix}/share/doc/${subport}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # The Perl components of Wallet server are installed by a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Module::Build installer that is normally run by the Makefile.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # PERL_INSTALL_ROOT is used to set the destroot path; we don't
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # set a prefix because that is already configured into MacPorts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Perl, and so Module::Build uses it automatically.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        system "env 'PERL_INSTALL_ROOT=${destroot}' '${prefix}/bin/perl${perl5.major}' '${worksrcpath}/perl/Build' 'install'"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # We have some post-activation setup that the user needs to do.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    notes-append "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Before using the Wallet server, you will need to choose a database
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+backend to use.  MySQL, Postgres, and SQLite are known to work.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Then you will need to install the p5-datetime-format-* and p5-dbd-*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ports that match the database backend you chose.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+If you want to support getting keytabs through Wallet, then your KDC
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+will need to have the wallet port installed with the +kdc variant.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Other Perl modules may be required, depending on what you want to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+support.  Read ${prefix}/share/doc/wallet/setup
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+for additional server configuration instructions.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Wallet server runs via remctl, so be sure that remctld is running,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and is configured correctly!
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# wallet-kdc just installs a couple of helper files that a Kerberos 5 KDC
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# can use to generate unchanging keytabs for a Wallet server.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# TODO: Patch keytab and wallet remctl config files to use ${destroot}${prefix}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+subport wallet-kdc {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    long_description-append This port contains a remctl script, to be \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            run on the Kerberos 5 KDC, that will generate \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            keytabs at the request of a Wallet server.  This \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            variant is only meant to be installed on a KDC, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            and does not include Wallet server or client.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # We have our own destroot process, to install just KDC bits.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    destroot {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # First, install common files from the distribution
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -d ${destroot}${prefix}/share/doc/${subport}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 644 ${worksrcpath}/LICENSE \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${worksrcpath}/NEWS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${worksrcpath}/README \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${worksrcpath}/TODO \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${destroot}${prefix}/share/doc/${subport}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Create some common directories.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # (These are also created by wallet-server)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -d ${destroot}${prefix}/etc/remctl/acl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -d ${destroot}${prefix}/etc/remctl/conf.d
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Install a stub KDC ACL that keytab-backend will use
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -d ${destroot}${prefix}/etc/krb5kdc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 640 ${worksrcpath}/config/allow-extract \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${destroot}${prefix}/etc/krb5kdc/allow-extract
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Install example remctl ACLs and configurations
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # ${destroot}${prefix}/etc/remctl/acl is created above
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 644 ${worksrcpath}/config/keytab.acl \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${destroot}${prefix}/etc/remctl/acl/keytab
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # ${destroot}${prefix}/etc/remctl/conf.d is created above
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 644 ${worksrcpath}/config/keytab \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${destroot}${prefix}/etc/remctl/conf.d/keytab
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Install the keytab-backend executable
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # ${destroot}${prefix}/sbin already exists
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 755 ${worksrcpath}/server/keytab-backend \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${destroot}${prefix}/sbin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Install the keytab-backend man page
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # ${destroot}${prefix}/share/man/man8 already exists
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 644 ${worksrcpath}/server/keytab-backend.8 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ${destroot}${prefix}/share/man/man8/keytab-backend.8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # We have soe post-activation setup that the user needs to do.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    notes-append "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+To configure your KDC to generate keytabs for the Wallet server,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+you will need to configure etc/krb5kdc/allow-extract, as well as
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/etc/remctl/acl/keytab.  This uses remctl, so remctld must also
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+be running and configured properly.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-Makefile.am.diff b/net/wallet/files/patch-Makefile.am.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..bb448cb
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-Makefile.am.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,118 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- Makefile.am.orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ Makefile.am
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -100,34 +100,36 @@ PERL_DIRECTORIES = perl perl/lib perl/lib/Wallet perl/lib/Wallet/ACL     \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   perl/t/policy perl/t/style perl/t/util perl/t/verifier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ACLOCAL_AMFLAGS = -I m4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-EXTRA_DIST = .gitignore .travis.yml LICENSE autogen client/wallet.pod         \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  client/wallet-rekey.pod config/allow-extract config/keytab          \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  config/keytab.acl config/wallet config/wallet-report.acl            \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  docs/design contrib/README contrib/commerzbank/wallet-history       \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  contrib/convert-srvtab-db contrib/used-principals                   \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  contrib/wallet-contacts contrib/wallet-rekey-periodic               \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  contrib/wallet-rekey-periodic.8 contrib/wallet-summary              \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  contrib/wallet-summary.8 contrib/wallet-unknown-hosts               \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  contrib/wallet-unknown-hosts.8 docs/design-acl docs/design-api      \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  docs/netdb-role-api docs/notes docs/objects-and-schemes docs/setup  \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  docs/stanford-naming examples/stanford.conf tests/HOWTO tests/TESTS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/config/README tests/data/allow-extract tests/data/basic.conf  \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/data/cmd-fake tests/data/cmd-wrapper tests/data/fake-data     \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/data/fake-kadmin tests/data/fake-keytab                       \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/data/fake-keytab-2 tests/data/fake-keytab-foreign             \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/data/fake-keytab-merge tests/data/fake-keytab-old             \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/data/fake-keytab-partial                                      \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/data/fake-keytab-partial-result tests/data/fake-keytab-rekey  \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/data/fake-keytab-unknown tests/data/fake-srvtab               \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/data/full.conf tests/data/perl.conf tests/data/wallet.conf    \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/docs/pod-spelling-t tests/docs/pod-t                          \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/perl/minimum-version-t tests/perl/module-version-t            \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/perl/strict-t tests/server/admin-t tests/server/backend-t     \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/server/keytab-t tests/server/report-t tests/tap/kerberos.sh   \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/tap/libtap.sh tests/tap/perl/Test/RRA.pm                      \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/tap/perl/Test/RRA/Automake.pm                                 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/tap/perl/Test/RRA/Config.pm                                   \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  tests/tap/perl/Test/RRA/ModuleVersion.pm tests/tap/remctl.sh        \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++EXTRA_DIST = .gitignore .travis.yml LICENSE autogen client/wallet.pod        \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  client/wallet-rekey.pod config/allow-extract config/keytab         \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  config/keytab.acl config/wallet config/wallet-report.acl           \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  docs/design contrib/README contrib/commerzbank/wallet-history      \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  contrib/convert-srvtab-db contrib/used-principals                  \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  contrib/wallet-contacts contrib/wallet-rekey-periodic              \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  contrib/wallet-rekey-periodic.8 contrib/wallet-summary             \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  contrib/wallet-summary.8 contrib/wallet-unknown-hosts              \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  contrib/wallet-unknown-hosts.8 docs/design-acl docs/design-api     \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  docs/netdb-role-api docs/notes docs/objects-and-schemes docs/setup \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  docs/stanford-naming examples/stanford.conf                        \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  server/keytab-backend.in server/wallet-admin.in                    \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  server/wallet-backend.in server/wallet-report.in tests/HOWTO       \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/TESTS tests/config/README tests/data/allow-extract           \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/data/basic.conf tests/data/cmd-fake tests/data/cmd-wrapper   \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/data/fake-data tests/data/fake-kadmin tests/data/fake-keytab \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/data/fake-keytab-2 tests/data/fake-keytab-foreign            \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/data/fake-keytab-merge tests/data/fake-keytab-old            \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/data/fake-keytab-partial                                     \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/data/fake-keytab-partial-result tests/data/fake-keytab-rekey \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/data/fake-keytab-unknown tests/data/fake-srvtab              \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/data/full.conf tests/data/perl.conf tests/data/wallet.conf   \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/docs/pod-spelling-t tests/docs/pod-t                         \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/perl/minimum-version-t tests/perl/module-version-t           \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/perl/strict-t tests/server/admin-t tests/server/backend-t    \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/server/keytab-t tests/server/report-t tests/tap/kerberos.sh  \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/tap/libtap.sh tests/tap/perl/Test/RRA.pm                     \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/tap/perl/Test/RRA/Automake.pm                                \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/tap/perl/Test/RRA/Config.pm                                  \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tests/tap/perl/Test/RRA/ModuleVersion.pm tests/tap/remctl.sh       \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   tests/util/xmalloc-t $(PERL_FILES)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Supporting convenience libraries used by other targets.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -150,7 +152,7 @@ client_libwallet_a_CPPFLAGS = $(REMCTL_CPPFLAGS) $(KRB5_CPPFLAGS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # The client and server programs.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bin_PROGRAMS = client/wallet client/wallet-rekey
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-dist_sbin_SCRIPTS = server/keytab-backend server/wallet-admin \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sbin_SCRIPTS = server/keytab-backend server/wallet-admin \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   server/wallet-backend server/wallet-report
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ client_wallet_CPPFLAGS = $(REMCTL_CPPFLAGS) $(KRB5_CPPFLAGS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ client_wallet_LDFLAGS = $(REMCTL_LDFLAGS) $(KRB5_LDFLAGS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -209,14 +211,30 @@ warnings:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       KRB5_CPPFLAGS='$(KRB5_CPPFLAGS_GCC)' $(check_PROGRAMS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Remove some additional files.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-CLEANFILES = perl/t/lib/Test/RRA.pm perl/t/lib/Test/RRA/Automake.pm \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  perl/t/lib/Test/RRA/Config.pm
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++CLEANFILES = perl/t/lib/Test/RRA.pm perl/t/lib/Test/RRA/Automake.pm       \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  perl/t/lib/Test/RRA/Config.pm server/keytab-backend             \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  server/wallet-admin server/wallet-backend server/wallet-report
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 build-aux/compile                \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   build-aux/depcomp build-aux/install-sh build-aux/missing             \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   client/wallet.1 config.h.in config.h.in~ configure                   \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   contrib/wallet-report.8 server/keytab-backend.8                      \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   server/wallet-admin.8 server/wallet-backend.8 server/wallet-report.8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# For each of the Perl scripts, we need to fill in the path to the Perl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# binary that was located during configuration.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++server/keytab-backend: $(srcdir)/server/keytab-backend.in Makefile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  sed 's|\@PERL\@|$(PERL)|' <$(srcdir)/server/keytab-backend.in >$@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  chmod a+x $@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++server/wallet-admin: $(srcdir)/server/wallet-admin.in Makefile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  sed 's|\@PERL\@|$(PERL)|' <$(srcdir)/server/wallet-admin.in >$@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  chmod a+x $@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++server/wallet-backend: $(srcdir)/server/wallet-backend.in Makefile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  sed 's|\@PERL\@|$(PERL)|' <$(srcdir)/server/wallet-backend.in >$@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  chmod a+x $@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++server/wallet-report: $(srcdir)/server/wallet-report.in Makefile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  sed 's|\@PERL\@|$(PERL)|' <$(srcdir)/server/wallet-report.in >$@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  chmod a+x $@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Take appropriate actions in the Perl directory as well.  We don't want to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # always build the Perl directory in all-local, since otherwise Automake does
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # this for every target, which overrides some hacks we have to do for Debian
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -236,7 +254,7 @@ perl/blib/lib/Wallet/Config.pm: $(srcdir)/perl/lib/Wallet/Config.pm
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   $(INSTALL_DATA) $(srcdir)/tests/tap/perl/Test/RRA.pm perl/t/lib/Test/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   $(INSTALL_DATA) $(srcdir)/tests/tap/perl/Test/RRA/Config.pm \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       perl/t/lib/Test/RRA/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  cd perl && perl Build.PL $(WALLET_PERL_FLAGS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  cd perl && $(PERL) Build.PL $(WALLET_PERL_FLAGS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cd perl && ./Build
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # This is a really ugly hack to only honor prefix when running make install
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-README.diff b/net/wallet/files/patch-README.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..87c92e1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-README.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,28 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- README.orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ README
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -183,14 +183,21 @@ BUILD AND INSTALLATION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   must be specified either in krb5.conf configuration or on the wallet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   command line or the client will exit with an error.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  By default, wallet uses whatever perl executable exists in the current $PATH.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  That Perl's path is what the server scripts will use, and that Perl's
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  configuration will be used to determine where the server Perl modules will be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  installed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  To specify a particular Perl executable to use, either set the PERL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  environment variable or pass it to configure like:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      ./configure PERL=/path/to/my/perl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   By default, wallet installs itself under /usr/local except for the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   server Perl modules, which are installed into whatever default site
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   module path is used by your Perl installation.  To change the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   installation location of the files other than the Perl modules, pass the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  --prefix=DIR argument to configure.  To change the Perl module
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  installation location, you will need to run perl on Makefile.PL in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  perl subdirectory of the build tree with appropriate options and rebuild
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  the module after running make and before running make install.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  --prefix=DIR argument to configure.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   If remctl was installed in a path not normally searched by your
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   compiler, you must specify its installation prefix to configure with the
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-autogen.diff b/net/wallet/files/patch-autogen.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..94ee01a
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-autogen.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,22 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- autogen.orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ autogen
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -13,10 +13,15 @@ for doc in client/wallet client/wallet-rekey ; do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     pod2man --release="$version" --center=wallet \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         --name=`basename "$doc" | tr a-z A-Z` "$doc".pod > "$doc".1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ done
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-for doc in contrib/wallet-rekey-periodic contrib/wallet-summary \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-           contrib/wallet-unknown-hosts server/keytab-backend   \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-           server/wallet-admin server/wallet-backend            \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-           server/wallet-report ; do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++for doc in contrib/wallet-rekey-periodic contrib/wallet-summary  \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++           contrib/wallet-unknown-hosts ; do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     pod2man --release="$version" --center=wallet --section=8 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         --name=`basename "$doc" | tr a-z A-Z` "$doc" > "$doc".8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ done
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++for doc in server/keytab-backend server/wallet-admin \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++           server/wallet-admin server/wallet-backend \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++           server/wallet-report ; do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    pod2man --release="$version" --center=wallet --section=8 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        --name=`basename "$doc" | tr a-z A-Z` "$doc.in" > "$doc".8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++done
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-configure.ac.diff b/net/wallet/files/patch-configure.ac.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..b1cfeae
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-configure.ac.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,25 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- configure.ac.orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ configure.ac
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -45,6 +45,14 @@ AC_ARG_WITH([wallet-port],
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         [AC_DEFINE_UNQUOTED([WALLET_PORT], [$withval],
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             [Define to the default server port.])])])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++dnl Determine the path to the Perl binary.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++AC_ARG_VAR([PERL], [Path to the Perl binary])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++AC_PATH_PROG([PERL], [perl])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++AS_IF([test -z "$PERL"],
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    [AC_MSG_ERROR([Could not find Perl binary (set PERL to the full path)])])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++AS_IF(["$PERL" -e 'require 5.008'], [:],
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    [AC_MSG_ERROR([Perl 5.8 or better is required])])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dnl Probe for required libraries.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ RRA_LIB_REMCTL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ RRA_LIB_KRB5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -90,6 +98,7 @@ AC_CONFIG_FILES([tests/client/basic-t], [chmod +x tests/client/basic-t])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ AC_CONFIG_FILES([tests/client/full-t], [chmod +x tests/client/full-t])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ AC_CONFIG_FILES([tests/client/prompt-t], [chmod +x tests/client/prompt-t])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ AC_CONFIG_FILES([tests/client/rekey-t], [chmod +x tests/client/rekey-t])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++AC_CONFIG_COMMANDS([server], [test -d server || mkdir server])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ AC_CONFIG_COMMANDS([tests/config],
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     [test -d tests/config || mkdir tests/config])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ AC_OUTPUT
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-perl-Build.PL.diff b/net/wallet/files/patch-perl-Build.PL.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..2c68174
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-perl-Build.PL.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,13 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- perl/Build.PL.orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ perl/Build.PL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -48,6 +48,10 @@ my $build = Module::Build->new(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         'Net::Remctl'              => 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         WebAuth                    => 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    test_requires => {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        'Crypt::GeneratePassword'  => 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        'DateTime::Format::SQLite' => 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Generate the build script.
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-portable-system.h.diff b/net/wallet/files/patch-portable-system.h.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..8ea5b00
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-portable-system.h.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,15 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- portable/system.h.orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ portable/system.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -136,12 +136,6 @@ extern void *reallocarray(void *, size_t, size_t);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #if !HAVE_SETENV
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ extern int setenv(const char *, const char *, int);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#if !HAVE_DECL_STRLCAT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-extern size_t strlcat(char *, const char *, size_t);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#if !HAVE_DECL_STRLCPY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-extern size_t strlcpy(char *, const char *, size_t);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Undo default visibility change. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #pragma GCC visibility pop
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-rename-server-keytab-backend.diff b/net/wallet/files/patch-rename-server-keytab-backend.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..bc3dd14
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-rename-server-keytab-backend.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,496 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- server/keytab-backend  2016-01-17 19:13:02.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ /dev/null      2016-01-23 13:57:05.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1,245 +0,0 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#!/usr/bin/perl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Extract keytabs from the KDC without changing the key.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# This is a remctl backend that extracts existing keys from a KDC database
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# using kadmin.local.  It requires a patched version of kadmin.local that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# supports the -norandkey option.  It expects a configuration file in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# /etc/krb5kdc/allow-extract that contains a list of regexes, one per line,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# matching principals that may be extracted in this fashion.  (Generally you
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# do not want to list user principals here.)  It also expects to be able to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# write to a directory named /var/lib/keytabs; that's where it puts the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# keytabs temporarily before sending them back to via remctl.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# remctl should handle authorization restrictions on this script.  It doesn't
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# do any additional authorization checks itself.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# The keytab for the extracted principal will be printed to standard output.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use 5.008;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use strict;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use warnings;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use Sys::Syslog qw(openlog syslog);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Path to configuration file listing principals that may be extracted.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-our $CONFIG = '/etc/krb5kdc/allow-extract';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# The full path to a kadmin.local that supports -norandkey.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-our $KADMIN = '/usr/sbin/kadmin.local';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# A temporary area into which keytabs should be written.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-our $TMP = '/var/lib/keytabs';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Set to zero to suppress syslog logging, which is used only for testing.  Set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# to a reference to a string to append messages to that string instead.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-our $SYSLOG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-$SYSLOG = 1 unless defined $SYSLOG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Logging
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Initialize logging.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub log_init {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $$SYSLOG = '';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        openlog ('keytab-backend', 'pid', 'auth');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Log a failure message to both syslog and to stderr and exit with a non-zero
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# status.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub error {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $message = join ('', @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $$SYSLOG .= $message . "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        syslog ('err', '%s', $message);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    die "keytab-backend: $message\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Log a regular message, generally for success.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub info {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $message = join ('', @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $$SYSLOG .= $message . "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        syslog ('info', '%s', $message);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Implementation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Check and download the keytab.  This is in a subroutine call for easier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# testing.  We separately log actions unless $SYSLOG is set to 0.  remctld
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# keeps some logs, but it won't tell us whether the download is successful or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# not.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub download {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my (@args) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    log_init;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    # Set up a default identity if run from the command line.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    $ENV{REMOTE_USER} = getpwnam ($<) || 'UNKNOWN' unless $ENV{REMOTE_USER};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    # Read the regexes of valid principals into memory.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    open (CONFIG, '<', $CONFIG) or error "cannot open $CONFIG: $!";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my @valid;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    while (<CONFIG>) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        next if /^\s*\#/;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        next if /^\s*$/;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        s/^\s+//;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        s/\s+$//;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        s/\s*\#.*//;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        push (@valid, qr/$_/);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    close CONFIG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    # The first argument will be the remctl service, so skip it.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (@args == 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        shift @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (@args != 1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        error "invalid arguments: @args";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $principal = $args[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    # Ensure that we're allowed to retrieve this principal.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    unless ($principal =~ m%^[\w-]+(?:/[\w.-]+)?\@[\w.-]+\z%) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        error "bad principal name $principal";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $okay;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    for my $regex (@valid) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if ($principal =~ /$regex/) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $okay = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            last;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    unless ($okay) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        error "permission denied: $ENV{REMOTE_USER} may not retrieve"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            . " $principal";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    # Do the actual work.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $filename = "$TMP/keytab$$";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $command = "ktadd -k $filename -q -norandkey $principal";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $output = `$KADMIN -q '$command' 2>&1`;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if ($? != 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $status = ($? >> 8);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        warn $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        error "retrieve of $principal failed for $ENV{REMOTE_USER}:"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            . " kadmin.local exited with status $status";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    open (KEYTAB, '<', $filename)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        or error "cannot open temporary keytab $filename: $!";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    print while <KEYTAB>;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    close KEYTAB;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    unlink $filename;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    info ("keytab $principal retrieved by $ENV{REMOTE_USER}");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-download (@ARGV);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-__END__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Documentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=for stopwords
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-keytab-backend keytabs KDC keytab kadmin.local -norandkey ktadd remctld
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-auth Allbery rekeying MERCHANTABILITY NONINFRINGEMENT sublicense
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-kadmin.local.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 NAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-keytab-backend - Extract keytabs from the KDC without changing the key
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 SYNOPSIS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<keytab-backend> retrieve I<principal>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 DESCRIPTION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<keytab-backend> retrieves a keytab for an existing principal from the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-KDC database without changing the current key.  It allows generation of a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-keytab for a service without rekeying that service.  It requires a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<kadmin.local> patched to support the B<-norandkey> option to B<ktadd>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-This script is intended to run under B<remctld>.  On success, it prints
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the keytab to standard output, logs a success message to syslog (facility
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-auth, priority info), and exits with status 0.  On failure, it prints out
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-an error message, logs an error to syslog (facility auth, priority err),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and exits with a non-zero status.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The principal is checked for basic sanity (only accepting alphanumerics,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<_>, and C<-> with an optional instance and then only alphanumerics,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<_>, C<->, and C<.> in the realm) and then checked against a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-configuration file that lists regexes of principals that can be retrieved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-When deploying this software, limit as tightly as possible which
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-principals can be downloaded in this fashion.  Generally only shared
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-service principals used on multiple systems should be made available in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-this way.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<keytab-backend> does not do any authorization checks.  Those should be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-done by B<remctld> before it is called.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 FILES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item F</etc/krb5kdc/allow-extract>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The configuration file that controls which principals can have their
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-keytabs retrieved.  Blank lines and lines starting with C<#>, as well as
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-anything after C<#> on a line, are ignored.  All other lines should be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Perl regular expressions, one per line, that match principals whose
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-keytabs can be retrieved by B<keytab-backend>.  Any principal that does
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-not match one of those regular expressions cannot be retrieved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item F</var/lib/keytabs>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The temporary directory used for creating keytabs.  B<keytab-backend> will
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-create the keytab in this directory, make sure that was successful, and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-then delete the temporary file after the results have been sent to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-standard output.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 AUTHOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Russ Allbery <eagle@eyrie.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 COPYRIGHT AND LICENSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Copyright 2006, 2007, 2008, 2010, 2013 The Board of Trustees of the Leland
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Stanford Junior University
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Permission is hereby granted, free of charge, to any person obtaining a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-copy of this software and associated documentation files (the "Software"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-to deal in the Software without restriction, including without limitation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the rights to use, copy, modify, merge, publish, distribute, sublicense,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and/or sell copies of the Software, and to permit persons to whom the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Software is furnished to do so, subject to the following conditions:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The above copyright notice and this permission notice shall be included in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-all copies or substantial portions of the Software.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-DEALINGS IN THE SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 SEE ALSO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-kadmin.local(8), remctld(8)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-This program is part of the wallet system.  The current version is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-available from L<http://www.eyrie.org/~eagle/software/wallet/>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=cut
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null      2016-01-23 13:57:05.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ server/keytab-backend.in       2016-01-17 19:13:02.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,245 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#!@PERL@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Extract keytabs from the KDC without changing the key.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# This is a remctl backend that extracts existing keys from a KDC database
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# using kadmin.local.  It requires a patched version of kadmin.local that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# supports the -norandkey option.  It expects a configuration file in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# /etc/krb5kdc/allow-extract that contains a list of regexes, one per line,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# matching principals that may be extracted in this fashion.  (Generally you
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# do not want to list user principals here.)  It also expects to be able to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# write to a directory named /var/lib/keytabs; that's where it puts the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# keytabs temporarily before sending them back to via remctl.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# remctl should handle authorization restrictions on this script.  It doesn't
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# do any additional authorization checks itself.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# The keytab for the extracted principal will be printed to standard output.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use 5.008;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use strict;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use warnings;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use Sys::Syslog qw(openlog syslog);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Path to configuration file listing principals that may be extracted.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++our $CONFIG = '/etc/krb5kdc/allow-extract';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# The full path to a kadmin.local that supports -norandkey.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++our $KADMIN = '/usr/sbin/kadmin.local';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# A temporary area into which keytabs should be written.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++our $TMP = '/var/lib/keytabs';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Set to zero to suppress syslog logging, which is used only for testing.  Set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# to a reference to a string to append messages to that string instead.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++our $SYSLOG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++$SYSLOG = 1 unless defined $SYSLOG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Logging
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Initialize logging.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub log_init {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $$SYSLOG = '';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        openlog ('keytab-backend', 'pid', 'auth');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Log a failure message to both syslog and to stderr and exit with a non-zero
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# status.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub error {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $message = join ('', @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $$SYSLOG .= $message . "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        syslog ('err', '%s', $message);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    die "keytab-backend: $message\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Log a regular message, generally for success.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub info {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $message = join ('', @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $$SYSLOG .= $message . "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        syslog ('info', '%s', $message);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Implementation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Check and download the keytab.  This is in a subroutine call for easier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# testing.  We separately log actions unless $SYSLOG is set to 0.  remctld
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# keeps some logs, but it won't tell us whether the download is successful or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# not.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub download {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my (@args) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    log_init;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    # Set up a default identity if run from the command line.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    $ENV{REMOTE_USER} = getpwnam ($<) || 'UNKNOWN' unless $ENV{REMOTE_USER};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    # Read the regexes of valid principals into memory.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    open (CONFIG, '<', $CONFIG) or error "cannot open $CONFIG: $!";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my @valid;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    while (<CONFIG>) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        next if /^\s*\#/;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        next if /^\s*$/;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        s/^\s+//;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        s/\s+$//;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        s/\s*\#.*//;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        push (@valid, qr/$_/);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    close CONFIG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    # The first argument will be the remctl service, so skip it.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (@args == 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        shift @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (@args != 1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        error "invalid arguments: @args";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $principal = $args[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    # Ensure that we're allowed to retrieve this principal.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    unless ($principal =~ m%^[\w-]+(?:/[\w.-]+)?\@[\w.-]+\z%) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        error "bad principal name $principal";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $okay;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    for my $regex (@valid) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if ($principal =~ /$regex/) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $okay = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            last;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    unless ($okay) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        error "permission denied: $ENV{REMOTE_USER} may not retrieve"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            . " $principal";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    # Do the actual work.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $filename = "$TMP/keytab$$";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $command = "ktadd -k $filename -q -norandkey $principal";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $output = `$KADMIN -q '$command' 2>&1`;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if ($? != 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $status = ($? >> 8);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        warn $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        error "retrieve of $principal failed for $ENV{REMOTE_USER}:"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            . " kadmin.local exited with status $status";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    open (KEYTAB, '<', $filename)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        or error "cannot open temporary keytab $filename: $!";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    print while <KEYTAB>;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    close KEYTAB;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    unlink $filename;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    info ("keytab $principal retrieved by $ENV{REMOTE_USER}");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++download (@ARGV);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++__END__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Documentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=for stopwords
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++keytab-backend keytabs KDC keytab kadmin.local -norandkey ktadd remctld
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++auth Allbery rekeying MERCHANTABILITY NONINFRINGEMENT sublicense
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++kadmin.local.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 NAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++keytab-backend - Extract keytabs from the KDC without changing the key
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 SYNOPSIS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<keytab-backend> retrieve I<principal>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 DESCRIPTION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<keytab-backend> retrieves a keytab for an existing principal from the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++KDC database without changing the current key.  It allows generation of a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++keytab for a service without rekeying that service.  It requires a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<kadmin.local> patched to support the B<-norandkey> option to B<ktadd>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++This script is intended to run under B<remctld>.  On success, it prints
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the keytab to standard output, logs a success message to syslog (facility
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++auth, priority info), and exits with status 0.  On failure, it prints out
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++an error message, logs an error to syslog (facility auth, priority err),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and exits with a non-zero status.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The principal is checked for basic sanity (only accepting alphanumerics,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<_>, and C<-> with an optional instance and then only alphanumerics,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<_>, C<->, and C<.> in the realm) and then checked against a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++configuration file that lists regexes of principals that can be retrieved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++When deploying this software, limit as tightly as possible which
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++principals can be downloaded in this fashion.  Generally only shared
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++service principals used on multiple systems should be made available in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++this way.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<keytab-backend> does not do any authorization checks.  Those should be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++done by B<remctld> before it is called.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 FILES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item F</etc/krb5kdc/allow-extract>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The configuration file that controls which principals can have their
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++keytabs retrieved.  Blank lines and lines starting with C<#>, as well as
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++anything after C<#> on a line, are ignored.  All other lines should be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Perl regular expressions, one per line, that match principals whose
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++keytabs can be retrieved by B<keytab-backend>.  Any principal that does
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++not match one of those regular expressions cannot be retrieved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item F</var/lib/keytabs>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The temporary directory used for creating keytabs.  B<keytab-backend> will
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++create the keytab in this directory, make sure that was successful, and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++then delete the temporary file after the results have been sent to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++standard output.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 AUTHOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Russ Allbery <eagle@eyrie.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 COPYRIGHT AND LICENSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Copyright 2006, 2007, 2008, 2010, 2013 The Board of Trustees of the Leland
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Stanford Junior University
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Permission is hereby granted, free of charge, to any person obtaining a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++copy of this software and associated documentation files (the "Software"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++to deal in the Software without restriction, including without limitation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the rights to use, copy, modify, merge, publish, distribute, sublicense,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and/or sell copies of the Software, and to permit persons to whom the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Software is furnished to do so, subject to the following conditions:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The above copyright notice and this permission notice shall be included in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++all copies or substantial portions of the Software.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++DEALINGS IN THE SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 SEE ALSO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++kadmin.local(8), remctld(8)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++This program is part of the wallet system.  The current version is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++available from L<http://www.eyrie.org/~eagle/software/wallet/>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=cut
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-rename-server-wallet-admin.diff b/net/wallet/files/patch-rename-server-wallet-admin.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..e3a6f89
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-rename-server-wallet-admin.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,356 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- server/wallet-admin    2016-01-17 19:13:02.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ /dev/null      2016-01-23 14:00:27.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1,175 +0,0 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#!/usr/bin/perl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Wallet server administrative commands.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use 5.008;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use strict;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use warnings;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use Wallet::Admin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Implementation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Parse and execute a command.  We wrap this in a subroutine call for easier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# testing.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub command {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    die "Usage: wallet-admin <command> [<args> ...]\n" unless @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $admin = Wallet::Admin->new;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    # Parse command-line options and dispatch to the appropriate calls.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my ($command, @args) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if ($command eq 'destroy') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too many arguments to destroy\n" if @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        print 'This will delete all data in the wallet database.  Are you'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            . ' sure (N/y)? ';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $response = <STDIN>;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        unless ($response and $response =~ /^y/i) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            die "Aborted\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $admin->destroy or die $admin->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'initialize') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too many arguments to initialize\n" if @args > 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too few arguments to initialize\n" if @args < 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "invalid admin principal $args[0]\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            unless $args[0] =~ /^[^\@\s]+\@\S+$/;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $admin->initialize (@args) or die $admin->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'register') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too many arguments to register\n" if @args > 3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too few arguments to register\n" if @args < 3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my ($object, $type, $class) = @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if ($object eq 'object') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            unless ($admin->register_object ($type, $class)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                die $admin->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif ($object eq 'verifier') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            unless ($admin->register_verifier ($type, $class)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                die $admin->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            die "only object or verifier is supported for register\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'upgrade') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too many arguments to upgrade\n" if @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $admin->upgrade or die $admin->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "unknown command $command\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-command (@ARGV);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-__END__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Documentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=for stopwords
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-metadata ACL hostname backend acl acls wildcard SQL Allbery verifier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-MERCHANTABILITY NONINFRINGEMENT sublicense
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 NAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-wallet-admin - Wallet server administrative commands
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 SYNOPSIS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<wallet-admin> I<command> [I<args> ...]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 DESCRIPTION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<wallet-admin> provides a command-line interface for performing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-administrative actions for the wallet system, such as setting up a new
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-database or running reports.  It is intended to be run on the wallet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-server as a user with access to the wallet database and configuration.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-This program is a fairly thin wrapper around Wallet::Admin that translates
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-command strings into method calls and returns the results.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 OPTIONS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<wallet-admin> takes no traditional options.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 COMMANDS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item destroy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Deletes all data in the wallet database and drops all of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-wallet-created tables, restoring the database to its state prior to an
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<initialize> command.  Since this command is destructive and cannot be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-easily recovered from, B<wallet-admin> will prompt first to be sure the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-user intends to do this.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item initialize <principal>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Given an empty database, initializes it for use with the wallet server by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-creating the necessary tables and initial metadata.  Also creates an ACL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-with the name ADMIN, used for administrative privileges to the wallet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-system, and adds an ACL entry to it with a scheme of C<krb5> and an
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-instance of <principal>.  This bootstraps the authentication system and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-allows that user to make further changes to the ADMIN ACL and the rest of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the wallet database.  C<initialize> uses C<localhost> as the hostname and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-<principal> as the user when logging the history of the ADMIN ACL creation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and for any subsequent actions required to initialize the database.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Before running C<initialize>, the wallet system has to be configured.  See
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Wallet::Config(3) for more details.  Depending on the database backend
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-used, the database may also have to be created in advance.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item register (object | verifier) <type> <class>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Registers an implementation of a wallet object or ACL verifier in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-wallet database.  The Perl class <class> is registered as the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-implementation of an object of type <type> or an ACL verifier of scheme
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-<type>, allowing creation of objects with that type or ACL lines with that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-scheme.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-All object and ACL implementations that come with wallet are registered by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-default as part of database initialization, so this command is used
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-primarily to register local implementations of additional object types or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-ACL schemes.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item upgrade
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Upgrades the database to the latest schema version, preserving data as
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-much as possible.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 AUTHOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Russ Allbery <eagle@eyrie.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 COPYRIGHT AND LICENSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Copyright 2008, 2009, 2010, 2011, 2013 The Board of Trustees of the Leland
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Stanford Junior University
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Permission is hereby granted, free of charge, to any person obtaining a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-copy of this software and associated documentation files (the "Software"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-to deal in the Software without restriction, including without limitation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the rights to use, copy, modify, merge, publish, distribute, sublicense,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and/or sell copies of the Software, and to permit persons to whom the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Software is furnished to do so, subject to the following conditions:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The above copyright notice and this permission notice shall be included in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-all copies or substantial portions of the Software.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-DEALINGS IN THE SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 SEE ALSO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Wallet::Admin(3), Wallet::Config(3), wallet-backend(8)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-This program is part of the wallet system.  The current version is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-available from L<http://www.eyrie.org/~eagle/software/wallet/>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=cut
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null      2016-01-23 14:00:27.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ server/wallet-admin.in 2016-01-17 19:13:02.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,175 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#!@PERL@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Wallet server administrative commands.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use 5.008;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use strict;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use warnings;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use Wallet::Admin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Implementation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Parse and execute a command.  We wrap this in a subroutine call for easier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# testing.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub command {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    die "Usage: wallet-admin <command> [<args> ...]\n" unless @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $admin = Wallet::Admin->new;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    # Parse command-line options and dispatch to the appropriate calls.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my ($command, @args) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if ($command eq 'destroy') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too many arguments to destroy\n" if @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        print 'This will delete all data in the wallet database.  Are you'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            . ' sure (N/y)? ';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $response = <STDIN>;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        unless ($response and $response =~ /^y/i) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            die "Aborted\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $admin->destroy or die $admin->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'initialize') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too many arguments to initialize\n" if @args > 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too few arguments to initialize\n" if @args < 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "invalid admin principal $args[0]\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            unless $args[0] =~ /^[^\@\s]+\@\S+$/;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $admin->initialize (@args) or die $admin->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'register') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too many arguments to register\n" if @args > 3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too few arguments to register\n" if @args < 3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my ($object, $type, $class) = @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if ($object eq 'object') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            unless ($admin->register_object ($type, $class)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                die $admin->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif ($object eq 'verifier') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            unless ($admin->register_verifier ($type, $class)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                die $admin->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            die "only object or verifier is supported for register\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'upgrade') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too many arguments to upgrade\n" if @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $admin->upgrade or die $admin->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "unknown command $command\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++command (@ARGV);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++__END__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Documentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=for stopwords
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++metadata ACL hostname backend acl acls wildcard SQL Allbery verifier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++MERCHANTABILITY NONINFRINGEMENT sublicense
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 NAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++wallet-admin - Wallet server administrative commands
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 SYNOPSIS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<wallet-admin> I<command> [I<args> ...]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 DESCRIPTION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<wallet-admin> provides a command-line interface for performing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++administrative actions for the wallet system, such as setting up a new
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++database or running reports.  It is intended to be run on the wallet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++server as a user with access to the wallet database and configuration.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++This program is a fairly thin wrapper around Wallet::Admin that translates
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++command strings into method calls and returns the results.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 OPTIONS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<wallet-admin> takes no traditional options.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 COMMANDS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item destroy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Deletes all data in the wallet database and drops all of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++wallet-created tables, restoring the database to its state prior to an
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<initialize> command.  Since this command is destructive and cannot be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++easily recovered from, B<wallet-admin> will prompt first to be sure the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++user intends to do this.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item initialize <principal>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Given an empty database, initializes it for use with the wallet server by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++creating the necessary tables and initial metadata.  Also creates an ACL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++with the name ADMIN, used for administrative privileges to the wallet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++system, and adds an ACL entry to it with a scheme of C<krb5> and an
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++instance of <principal>.  This bootstraps the authentication system and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++allows that user to make further changes to the ADMIN ACL and the rest of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the wallet database.  C<initialize> uses C<localhost> as the hostname and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<principal> as the user when logging the history of the ADMIN ACL creation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and for any subsequent actions required to initialize the database.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Before running C<initialize>, the wallet system has to be configured.  See
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Wallet::Config(3) for more details.  Depending on the database backend
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++used, the database may also have to be created in advance.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item register (object | verifier) <type> <class>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Registers an implementation of a wallet object or ACL verifier in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++wallet database.  The Perl class <class> is registered as the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++implementation of an object of type <type> or an ACL verifier of scheme
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<type>, allowing creation of objects with that type or ACL lines with that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++scheme.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++All object and ACL implementations that come with wallet are registered by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++default as part of database initialization, so this command is used
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++primarily to register local implementations of additional object types or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ACL schemes.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item upgrade
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Upgrades the database to the latest schema version, preserving data as
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++much as possible.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 AUTHOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Russ Allbery <eagle@eyrie.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 COPYRIGHT AND LICENSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Copyright 2008, 2009, 2010, 2011, 2013 The Board of Trustees of the Leland
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Stanford Junior University
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Permission is hereby granted, free of charge, to any person obtaining a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++copy of this software and associated documentation files (the "Software"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++to deal in the Software without restriction, including without limitation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the rights to use, copy, modify, merge, publish, distribute, sublicense,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and/or sell copies of the Software, and to permit persons to whom the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Software is furnished to do so, subject to the following conditions:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The above copyright notice and this permission notice shall be included in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++all copies or substantial portions of the Software.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++DEALINGS IN THE SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 SEE ALSO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Wallet::Admin(3), Wallet::Config(3), wallet-backend(8)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++This program is part of the wallet system.  The current version is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++available from L<http://www.eyrie.org/~eagle/software/wallet/>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=cut
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-rename-server-wallet-backend.diff b/net/wallet/files/patch-rename-server-wallet-backend.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..a7059d4
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-rename-server-wallet-backend.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,1396 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- server/wallet-backend  2016-01-17 19:13:02.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ /dev/null      2016-01-23 14:00:27.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1,695 +0,0 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#!/usr/bin/perl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Wallet server for storing and retrieving secure data.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use 5.008;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use strict;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use warnings;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use Getopt::Long qw(GetOptions);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use Sys::Syslog qw(openlog syslog);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use Wallet::Server;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Set to zero to suppress syslog logging, which is used for testing and for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# the -q option.  Set to a reference to a string to append messages to that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# string instead.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-our $SYSLOG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-$SYSLOG = 1 unless defined $SYSLOG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Logging
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Initialize logging.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub log_init {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $$SYSLOG = '';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        openlog ('wallet-backend', 'pid', 'auth');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Get an identity string for the user suitable for including in log messages.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub identity {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $identity = '';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if ($ENV{REMOTE_USER}) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $identity = $ENV{REMOTE_USER};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $host = $ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $identity .= " ($host)" if $host;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    return $identity;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Log an error message to both syslog and to stderr and exit with a non-zero
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# status.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub error {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $message = join ('', @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $identity = identity;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $log;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if ($identity) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $log = "error for $identity: $message";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $log = "error: $message";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $log =~ s/[^\x20-\x7e]/_/g;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $$SYSLOG .= "$log\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            syslog ('err', "%s", $log);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    die "$message\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Log a wallet failure message for a given command to both syslog and to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# stderr and exit with a non-zero status.  Takes the message and the command
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# that was being run.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub failure {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my ($message, @command) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $log = "command @command from " . identity . " failed: $message";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $log =~ s/[^\x20-\x7e]/_/g;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $$SYSLOG .= "$log\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            syslog ('err', "%s", $log);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    die "$message\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Log a wallet success message for a given command.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub success {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my (@command) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $log = "command @command from " . identity . " succeeded";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $log =~ s/[^\x20-\x7e]/_/g;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $$SYSLOG .= "$log\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            syslog ('info', "%s", $log);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Parameter checking
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Check all arguments against a very restricted set of allowed characters and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# to ensure the right number of arguments are taken.  The arguments are the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# number of arguments expected (minimum and maximum), a reference to an array
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# of which argument numbers shouldn't be checked, and then the arguments.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# This function is probably temporary and will be replaced with something that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# knows more about the syntax of each command and can check more things.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub check_args {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my ($min, $max, $exclude, @args) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (@args < $min) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        error "insufficient arguments";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif (@args > $max and $max != -1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        error "too many arguments";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my %exclude = map { $_ => 1 } @$exclude;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    for (my $i = 1; $i <= @args; $i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        next if $exclude{$i};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        unless ($args[$i - 1] =~ m,^[\w_/\@.-]*\z,) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            error "invalid characters in argument: $args[$i - 1]";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Implementation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Parse and execute a command.  We wrap this in a subroutine call for easier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# testing.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub command {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    log_init;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $user = $ENV{REMOTE_USER} or error "REMOTE_USER not set";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $host = $ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        or error "neither REMOTE_HOST nor REMOTE_ADDR set";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    # Instantiate the server object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $server = Wallet::Server->new ($user, $host);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    # Parse command-line options and dispatch to the appropriate calls.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my ($command, @args) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if ($command eq 'acl') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $action = shift @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if ($action eq 'add') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            check_args (3, 3, [3], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->acl_add (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif ($action eq 'check') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            check_args (1, 1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            my $status = $server->acl_check (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            if (!defined ($status)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print $status ? "yes\n" : "no\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif ($action eq 'create') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            check_args (1, 1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->acl_create (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif ($action eq 'destroy') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            check_args (1, 1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->acl_destroy (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif ($action eq 'history') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            check_args (1, 1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            my $output = $server->acl_history (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif ($action eq 'remove') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            check_args (3, 3, [3], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->acl_remove (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif ($action eq 'rename') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->acl_rename (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif ($action eq 'replace') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->acl_replace (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif ($action eq 'show') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            check_args (1, 1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            my $output = $server->acl_show (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            error "unknown command acl $action";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'autocreate') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $server->autocreate (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'check') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $status = $server->check (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (!defined ($status)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print $status ? "yes\n" : "no\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'comment') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 3, [3], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (@args > 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->comment (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            my $output = $server->comment (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print $output, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            } elsif (not $server->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print "No comment set\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'create') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $server->create (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'destroy') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $server->destroy (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'expires') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (@args > 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->expires (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            my $output = $server->expires (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print $output, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            } elsif (not $server->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print "No expiration set\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'flag') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $action = shift @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (3, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if ($action eq 'clear') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->flag_clear (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif ($action eq 'set') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->flag_set (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            error "unknown command flag $action";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'get') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $output = $server->get (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'getacl') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (3, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $output = $server->acl (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print $output, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif (not $server->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print "No ACL set\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'getattr') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (3, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my @result = $server->attr (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (not @result and $server->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif (@result) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print join ("\n", @result, '');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'history') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $output = $server->history (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'owner') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (@args > 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $server->owner (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            my $output = $server->owner (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print $output, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            } elsif (not $server->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print "No owner set\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'rename') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (3, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $server->rename (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'setacl') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (4, 4, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $server->acl (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'setattr') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (4, -1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $server->attr (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'show') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $output = $server->show (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'store') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 3, [3], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (@args == 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            local $/;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            $args[2] = <STDIN>;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        splice (@_, 3);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        $server->store (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'update') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my $output = $server->update (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        error "unknown command $command";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    success (@_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Parse command-line options.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-my ($quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Getopt::Long::config ('require_order');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-GetOptions ('q|quiet' => \$quiet) or exit 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-$SYSLOG = 0 if $quiet;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Run the command.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-command (@ARGV);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-__END__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Documentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# The commands section of this document is duplicated from the documentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# for wallet and should be kept in sync.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=for stopwords
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-wallet-backend backend backend-specific remctld ACL acl timestamp getacl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-setacl metadata keytab keytabs enctypes enctype ktadd KDC Allbery
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-autocreate MERCHANTABILITY NONINFRINGEMENT sublicense
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 NAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-wallet-backend - Wallet server for storing and retrieving secure data
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 SYNOPSIS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<wallet-backend> [B<-q>] I<command> [I<args> ...]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 DESCRIPTION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<wallet-backend> implements the interface between B<remctld> and the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-wallet system.  It is written to run under B<remctld> and expects the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-authenticated identity of the remote user in the REMOTE_USER environment
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-variable.  It uses REMOTE_HOST or REMOTE_ADDR if REMOTE_HOST isn't set for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-additional trace information.  It accepts the command from B<remctld> on
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the command line, creates a Wallet::Server object, and calls the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-appropriate methods.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-This program is a fairly thin wrapper around Wallet::Server that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-translates command strings into method calls and returns the results.  It
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-does check all arguments except for the <data> argument to the store
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-command and rejects any argument not matching C<^[\w_/.-]+\z>; in other
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-words, only alphanumerics, underscore (C<_>), slash (C</>), period (C<.>),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and hyphen (C<->) are permitted in arguments.  This provides some
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-additional security over and above the checking already done by the rest
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-of the wallet code.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 OPTIONS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item B<--quiet>, B<-q>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If this option is given, B<wallet-backend> will not log its actions to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-syslog.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 COMMANDS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Most commands are only available to wallet administrators (users on the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<ADMIN> ACL).  The exceptions are C<acl check>, C<check>, C<get>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<store>, C<show>, C<destroy>, C<flag clear>, C<flag set>, C<getattr>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<setattr>, and C<history>.  C<acl check> and C<check> can be run by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-anyone.  All of the rest of those commands have their own ACLs except
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<getattr> and C<history>, which use the C<show> ACL, C<setattr>, which
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-uses the C<store> ACL, and C<comment>, which uses the owner or C<show> ACL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-depending on whether one is setting or retrieving the comment.  If the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-appropriate ACL is set, it alone is checked to see if the user has access.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Otherwise, C<destroy>, C<get>, C<store>, C<show>, C<getattr>, C<setattr>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<history>, and C<comment> access is permitted if the user is authorized
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-by the owner ACL of the object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Administrators can run any command on any object or ACL except for C<get>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and C<store>.  For C<get> and C<store>, they must still be authorized by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-either the appropriate specific ACL or the owner ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If the locked flag is set on an object, no commands can be run on that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-object that change data except the C<flags> commands, nor can the C<get>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-command be used on that object.  C<show>, C<history>, C<getacl>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<getattr>, and C<owner>, C<comment>, or C<expires> without an argument
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-can still be used on that object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-For more information on attributes, see L<ATTRIBUTES>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acl add <id> <scheme> <identifier>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Add an entry with <scheme> and <identifier> to the ACL <id>.  <id> may be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-either the name of an ACL or its numeric identifier.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acl check <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Check whether an ACL with the ID <id> already exists.  If it does, prints
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<yes>; if not, prints C<no>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acl create <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Create a new, empty ACL with name <name>.  When setting an ACL on an
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-object with a set of entries that don't match an existing ACL, first
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-create a new ACL with C<acl create>, add the appropriate entries to it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-with C<acl add>, and then set the ACL on an object with the C<owner> or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<setacl> commands.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acl destroy <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Destroy the ACL <id>.  This ACL must no longer be referenced by any object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-or the ACL destruction will fail.  The special ACL named C<ADMIN> cannot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-be destroyed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acl history <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Display the history of the ACL <id>.  Each change to the ACL (not
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-including changes to the name of the ACL) will be represented by two
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-lines.  The first line will have a timestamp of the change followed by a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-description of the change, and the second line will give the user who made
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the change and the host from which the change was made.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acl remove <id> <scheme> <identifier>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Remove the entry with <scheme> and <identifier> from the ACL <id>.  <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-may be either the name of an ACL or its numeric identifier.  The last
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-entry in the special ACL C<ADMIN> cannot be removed to protect against
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-accidental lockout, but administrators can remove themselves from the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<ADMIN> ACL and can leave only a non-functioning entry on the ACL.  Use
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-caution when removing entries from the C<ADMIN> ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acl rename <id> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Renames the ACL identified by <id> to <name>.  This changes the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-human-readable name, not the underlying numeric ID, so the ACL's
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-associations with objects will be unchanged.  The C<ADMIN> ACL may not be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-renamed.  <id> may be either the current name or the numeric ID.  <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-must not be all-numeric.  To rename an ACL, the current user must be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-authorized by the C<ADMIN> ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acl replace <id> <new-id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Find any objects owned by <id>, and then change their ownership to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-<new_id> instead.  <new-id> should already exist, and may already have
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-some objects owned by it.  <id> is not deleted afterwards, though in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-most cases that is probably your next step.  The C<ADMIN> ACL may not be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-replaced from.  <id> and <new-id> may be either the current name or the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-numeric ID.  To replace an ACL, the current user must be authorized by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the C<ADMIN> ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acl show <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Display the name, numeric ID, and entries of the ACL <id>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item autocreate <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Create a new object of type <type> with name <name>.  The user must be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-listed in the default ACL for an object with that type and name, and the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-object will be created with that default ACL set as the object owner.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item check <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Check whether an object of type <type> and name <name> already exists.  If
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-it does, prints C<yes>; if not, prints C<no>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item comment <type> <name> [<comment>]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If <comment> is not given, displays the current comment for the object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-identified by <type> and <name>, or C<No comment set> if none is set.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If <comment> is given, sets the comment on the object identified by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-<type> and <name> to <comment>.  If <comment> is the empty string, clears
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the comment.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item create <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Create a new object of type <type> with name <name>.  With some backends,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-this will trigger creation of an entry in an external system as well.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The new object will have no ACLs and no owner set, so usually the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-administrator will want to then set an owner with C<owner> so that the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-object will be usable.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item destroy <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Destroy the object identified by <type> and <name>.  With some backends,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-this will trigger destruction of an object in an external system as well.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item expires <type> <name> [<date> [<time>]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If <date> is not given, displays the current expiration of the object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-identified by <type> and <name>, or C<No expiration set> if none is set.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The expiration will be displayed in seconds since epoch.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If <date> is given, sets the expiration on the object identified by <type>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and <name> to <date> and (if given) <time>.  <date> and <time> must be in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-some format that can be parsed by the Perl Date::Parse module.  Most
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-common formats are supported; if in doubt, use C<YYYY-MM-DD HH:MM:SS>.  If
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-<date> is the empty string, clears the expiration of the object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Currently, the expiration of an object is not used.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item flag clear <type> <name> <flag>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Clears the flag <flag> on the object identified by <type> and <name>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item flag set <type> <name> <flag>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Sets the flag <flag> on the object identified by <type> and <name>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Recognized flags are C<locked>, which prevents all further actions on that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-object until the flag is cleared, and C<unchanging>, which tells the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-object backend to not generate new data on get but instead return the same
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-data as previously returned.  The C<unchanging> flag is not meaningful for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-objects that do not generate new data on the fly.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item get <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Prints to standard output the data associated with the object identified
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-by <type> and <name>.  This may trigger generation of new data and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-invalidate old data for that object depending on the object type.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item getacl <type> <name> <acl>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Prints the ACL <acl>, which must be one of C<get>, C<store>, C<show>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<destroy>, or C<flags>, for the object identified by <type> and <name>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Prints C<No ACL set> if that ACL isn't set on that object.  Remember that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-if the C<get>, C<store>, or C<show> ACLs aren't set, authorization falls
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-back to checking the owner ACL.  See the C<owner> command for displaying
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-or setting it.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item getattr <type> <name> <attr>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Prints the object attribute <attr> for the object identified by <type> and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-<name>.  Attributes are used to store backend-specific information for a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-particular object type, and <attr> must be an attribute type known to the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-underlying object implementation.  The attribute values, if any, are
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-printed one per line.  If the attribute is not set on this object, nothing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-is printed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item history <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Displays the history for the object identified by <type> and <name>.  This
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-human-readable output will have two lines for each action that changes the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-object, plus for any get action.  The first line has the timestamp of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-action and the action, and the second line gives the user who performed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the action and the host from which they performed it.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item owner <type> <name> [<owner>]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If <owner> is not given, displays the current owner ACL of the object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-identified by <type> and <name>, or C<No owner set> if none is set.  The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-result will be the name of an ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If <owner> is given, sets the owner of the object identified by <type> and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-<name> to <owner>.  If <owner> is the empty string, clears the owner of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item rename <type> <name> <new-name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Renames an existing object.  This currently only supports file objects,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-where it renames the object itself, then the name and location of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-object in the file store.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item setacl <type> <name> <acl> <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Sets the ACL <acl>, which must be one of C<get>, C<store>, C<show>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<destroy>, or C<flags>, to <id> on the object identified by <type> and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-<name>.  If <id> is the empty string, clears that ACL on the object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item setattr <type> <name> <attr> <value> [<value> ...]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Sets the object attribute <attr> for the object identified by <type> and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-<name>.  Attributes are used to store backend-specific information for a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-particular object type, and <attr> must be an attribute type known to the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-underlying object implementation.  To clear the attribute for this object,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-pass in a <value> of the empty string (C<''>).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item show <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Displays the current object metadata for the object identified by <type>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and <name>.  This human-readable output will show the object type and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-name, the owner, any specific ACLs set on the object, the expiration if
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-any, and the user, remote host, and time when the object was created, last
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-stored, and last downloaded.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item store <type> <name> [<data>]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Stores <data> for the object identified by <type> and <name> for later
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-retrieval with C<get>.  Not all object types support this.  If <data> is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-not given as an argument, it will be read from standard input.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item update <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Prints to standard output the data associated with the object identified
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-by <type> and <name>.  If the object is one that can have changing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-information, such as a keytab or password, then we generate new data for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-that object regardless of whether there is current data or the unchanging
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-flag is set.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 ATTRIBUTES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Object attributes store additional properties and configuration
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-information for objects stored in the wallet.  They are displayed as part
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-of the object data with C<show>, retrieved with C<getattr>, and set with
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-C<setattr>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head2 Keytab Attributes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Keytab objects support the following attributes:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item enctypes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Restricts the generated keytab to a specific set of encryption types.  The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-values of this attribute must be enctype strings recognized by Kerberos
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-(strings like C<aes256-cts-hmac-sha1-96> or C<des-cbc-crc>).  Note that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the salt should not be included; since the salt is irrelevant for keytab
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-keys, it will always be set to C<normal> by the wallet.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If this attribute is set, the specified enctype list will be passed to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-ktadd when get() is called for that keytab.  If it is not set, the default
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-set in the KDC will be used.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-This attribute is ignored if the C<unchanging> flag is set on a keytab.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Keytabs retrieved with C<unchanging> set will contain all keys present in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the KDC for that Kerberos principal and therefore may contain different
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-enctypes than those requested by this attribute.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 AUTHOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Russ Allbery <eagle@eyrie.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 COPYRIGHT AND LICENSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Copyright 2007, 2008, 2010, 2011, 2012, 2013 The Board of Trustees of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Leland Stanford Junior University
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Permission is hereby granted, free of charge, to any person obtaining a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-copy of this software and associated documentation files (the "Software"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-to deal in the Software without restriction, including without limitation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the rights to use, copy, modify, merge, publish, distribute, sublicense,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and/or sell copies of the Software, and to permit persons to whom the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Software is furnished to do so, subject to the following conditions:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The above copyright notice and this permission notice shall be included in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-all copies or substantial portions of the Software.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-DEALINGS IN THE SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 SEE ALSO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Wallet::Server(3), remctld(8)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-This program is part of the wallet system.  The current version is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-available from L<http://www.eyrie.org/~eagle/software/wallet/>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=cut
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null      2016-01-23 14:00:27.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ server/wallet-backend.in       2016-01-17 19:13:02.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,695 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#!@PERL@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Wallet server for storing and retrieving secure data.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use 5.008;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use strict;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use warnings;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use Getopt::Long qw(GetOptions);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use Sys::Syslog qw(openlog syslog);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use Wallet::Server;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Set to zero to suppress syslog logging, which is used for testing and for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# the -q option.  Set to a reference to a string to append messages to that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# string instead.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++our $SYSLOG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++$SYSLOG = 1 unless defined $SYSLOG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Logging
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Initialize logging.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub log_init {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $$SYSLOG = '';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        openlog ('wallet-backend', 'pid', 'auth');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Get an identity string for the user suitable for including in log messages.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub identity {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $identity = '';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if ($ENV{REMOTE_USER}) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $identity = $ENV{REMOTE_USER};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $host = $ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $identity .= " ($host)" if $host;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return $identity;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Log an error message to both syslog and to stderr and exit with a non-zero
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# status.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub error {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $message = join ('', @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $identity = identity;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $log;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if ($identity) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $log = "error for $identity: $message";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $log = "error: $message";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $log =~ s/[^\x20-\x7e]/_/g;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $$SYSLOG .= "$log\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            syslog ('err', "%s", $log);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    die "$message\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Log a wallet failure message for a given command to both syslog and to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# stderr and exit with a non-zero status.  Takes the message and the command
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# that was being run.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub failure {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my ($message, @command) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $log = "command @command from " . identity . " failed: $message";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $log =~ s/[^\x20-\x7e]/_/g;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $$SYSLOG .= "$log\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            syslog ('err', "%s", $log);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    die "$message\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Log a wallet success message for a given command.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub success {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my (@command) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if ($SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $log = "command @command from " . identity . " succeeded";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $log =~ s/[^\x20-\x7e]/_/g;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (ref $SYSLOG) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $$SYSLOG .= "$log\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            syslog ('info', "%s", $log);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Parameter checking
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Check all arguments against a very restricted set of allowed characters and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# to ensure the right number of arguments are taken.  The arguments are the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# number of arguments expected (minimum and maximum), a reference to an array
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# of which argument numbers shouldn't be checked, and then the arguments.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# This function is probably temporary and will be replaced with something that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# knows more about the syntax of each command and can check more things.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub check_args {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my ($min, $max, $exclude, @args) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (@args < $min) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        error "insufficient arguments";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif (@args > $max and $max != -1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        error "too many arguments";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my %exclude = map { $_ => 1 } @$exclude;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    for (my $i = 1; $i <= @args; $i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        next if $exclude{$i};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        unless ($args[$i - 1] =~ m,^[\w_/\@.-]*\z,) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            error "invalid characters in argument: $args[$i - 1]";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Implementation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Parse and execute a command.  We wrap this in a subroutine call for easier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# testing.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub command {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    log_init;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $user = $ENV{REMOTE_USER} or error "REMOTE_USER not set";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $host = $ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        or error "neither REMOTE_HOST nor REMOTE_ADDR set";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    # Instantiate the server object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $server = Wallet::Server->new ($user, $host);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    # Parse command-line options and dispatch to the appropriate calls.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my ($command, @args) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if ($command eq 'acl') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $action = shift @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if ($action eq 'add') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            check_args (3, 3, [3], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->acl_add (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif ($action eq 'check') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            check_args (1, 1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            my $status = $server->acl_check (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            if (!defined ($status)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print $status ? "yes\n" : "no\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif ($action eq 'create') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            check_args (1, 1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->acl_create (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif ($action eq 'destroy') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            check_args (1, 1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->acl_destroy (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif ($action eq 'history') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            check_args (1, 1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            my $output = $server->acl_history (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif ($action eq 'remove') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            check_args (3, 3, [3], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->acl_remove (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif ($action eq 'rename') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->acl_rename (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif ($action eq 'replace') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->acl_replace (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif ($action eq 'show') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            check_args (1, 1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            my $output = $server->acl_show (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            error "unknown command acl $action";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'autocreate') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $server->autocreate (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'check') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $status = $server->check (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (!defined ($status)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print $status ? "yes\n" : "no\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'comment') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 3, [3], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (@args > 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->comment (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            my $output = $server->comment (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print $output, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            } elsif (not $server->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print "No comment set\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'create') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $server->create (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'destroy') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $server->destroy (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'expires') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (@args > 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->expires (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            my $output = $server->expires (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print $output, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            } elsif (not $server->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print "No expiration set\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'flag') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $action = shift @args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (3, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if ($action eq 'clear') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->flag_clear (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif ($action eq 'set') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->flag_set (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            error "unknown command flag $action";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'get') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $output = $server->get (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'getacl') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (3, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $output = $server->acl (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print $output, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif (not $server->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print "No ACL set\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'getattr') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (3, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my @result = $server->attr (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (not @result and $server->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif (@result) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print join ("\n", @result, '');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'history') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $output = $server->history (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'owner') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (@args > 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $server->owner (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            my $output = $server->owner (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print $output, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            } elsif (not $server->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print "No owner set\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'rename') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (3, 3, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $server->rename (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'setacl') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (4, 4, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $server->acl (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'setattr') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (4, -1, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $server->attr (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'show') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $output = $server->show (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'store') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 3, [3], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (@args == 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            local $/;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            $args[2] = <STDIN>;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        splice (@_, 3);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        $server->store (@args) or failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'update') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        check_args (2, 2, [], @args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my $output = $server->update (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (defined $output) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print $output;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            failure ($server->error, @_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        error "unknown command $command";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    success (@_);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Parse command-line options.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++my ($quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Getopt::Long::config ('require_order');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++GetOptions ('q|quiet' => \$quiet) or exit 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++$SYSLOG = 0 if $quiet;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Run the command.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++command (@ARGV);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++__END__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Documentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# The commands section of this document is duplicated from the documentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# for wallet and should be kept in sync.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=for stopwords
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++wallet-backend backend backend-specific remctld ACL acl timestamp getacl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++setacl metadata keytab keytabs enctypes enctype ktadd KDC Allbery
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++autocreate MERCHANTABILITY NONINFRINGEMENT sublicense
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 NAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++wallet-backend - Wallet server for storing and retrieving secure data
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 SYNOPSIS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<wallet-backend> [B<-q>] I<command> [I<args> ...]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 DESCRIPTION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<wallet-backend> implements the interface between B<remctld> and the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++wallet system.  It is written to run under B<remctld> and expects the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++authenticated identity of the remote user in the REMOTE_USER environment
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++variable.  It uses REMOTE_HOST or REMOTE_ADDR if REMOTE_HOST isn't set for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++additional trace information.  It accepts the command from B<remctld> on
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the command line, creates a Wallet::Server object, and calls the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++appropriate methods.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++This program is a fairly thin wrapper around Wallet::Server that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++translates command strings into method calls and returns the results.  It
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++does check all arguments except for the <data> argument to the store
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++command and rejects any argument not matching C<^[\w_/.-]+\z>; in other
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++words, only alphanumerics, underscore (C<_>), slash (C</>), period (C<.>),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and hyphen (C<->) are permitted in arguments.  This provides some
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++additional security over and above the checking already done by the rest
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++of the wallet code.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 OPTIONS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item B<--quiet>, B<-q>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If this option is given, B<wallet-backend> will not log its actions to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++syslog.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 COMMANDS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Most commands are only available to wallet administrators (users on the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<ADMIN> ACL).  The exceptions are C<acl check>, C<check>, C<get>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<store>, C<show>, C<destroy>, C<flag clear>, C<flag set>, C<getattr>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<setattr>, and C<history>.  C<acl check> and C<check> can be run by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++anyone.  All of the rest of those commands have their own ACLs except
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<getattr> and C<history>, which use the C<show> ACL, C<setattr>, which
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++uses the C<store> ACL, and C<comment>, which uses the owner or C<show> ACL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++depending on whether one is setting or retrieving the comment.  If the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++appropriate ACL is set, it alone is checked to see if the user has access.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Otherwise, C<destroy>, C<get>, C<store>, C<show>, C<getattr>, C<setattr>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<history>, and C<comment> access is permitted if the user is authorized
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++by the owner ACL of the object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Administrators can run any command on any object or ACL except for C<get>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and C<store>.  For C<get> and C<store>, they must still be authorized by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++either the appropriate specific ACL or the owner ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If the locked flag is set on an object, no commands can be run on that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++object that change data except the C<flags> commands, nor can the C<get>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++command be used on that object.  C<show>, C<history>, C<getacl>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<getattr>, and C<owner>, C<comment>, or C<expires> without an argument
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++can still be used on that object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++For more information on attributes, see L<ATTRIBUTES>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acl add <id> <scheme> <identifier>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Add an entry with <scheme> and <identifier> to the ACL <id>.  <id> may be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++either the name of an ACL or its numeric identifier.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acl check <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Check whether an ACL with the ID <id> already exists.  If it does, prints
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<yes>; if not, prints C<no>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acl create <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Create a new, empty ACL with name <name>.  When setting an ACL on an
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++object with a set of entries that don't match an existing ACL, first
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++create a new ACL with C<acl create>, add the appropriate entries to it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++with C<acl add>, and then set the ACL on an object with the C<owner> or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<setacl> commands.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acl destroy <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Destroy the ACL <id>.  This ACL must no longer be referenced by any object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++or the ACL destruction will fail.  The special ACL named C<ADMIN> cannot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++be destroyed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acl history <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Display the history of the ACL <id>.  Each change to the ACL (not
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++including changes to the name of the ACL) will be represented by two
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++lines.  The first line will have a timestamp of the change followed by a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++description of the change, and the second line will give the user who made
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the change and the host from which the change was made.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acl remove <id> <scheme> <identifier>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Remove the entry with <scheme> and <identifier> from the ACL <id>.  <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++may be either the name of an ACL or its numeric identifier.  The last
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++entry in the special ACL C<ADMIN> cannot be removed to protect against
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++accidental lockout, but administrators can remove themselves from the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<ADMIN> ACL and can leave only a non-functioning entry on the ACL.  Use
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++caution when removing entries from the C<ADMIN> ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acl rename <id> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Renames the ACL identified by <id> to <name>.  This changes the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++human-readable name, not the underlying numeric ID, so the ACL's
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++associations with objects will be unchanged.  The C<ADMIN> ACL may not be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++renamed.  <id> may be either the current name or the numeric ID.  <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++must not be all-numeric.  To rename an ACL, the current user must be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++authorized by the C<ADMIN> ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acl replace <id> <new-id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Find any objects owned by <id>, and then change their ownership to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<new_id> instead.  <new-id> should already exist, and may already have
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++some objects owned by it.  <id> is not deleted afterwards, though in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++most cases that is probably your next step.  The C<ADMIN> ACL may not be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++replaced from.  <id> and <new-id> may be either the current name or the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++numeric ID.  To replace an ACL, the current user must be authorized by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the C<ADMIN> ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acl show <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Display the name, numeric ID, and entries of the ACL <id>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item autocreate <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Create a new object of type <type> with name <name>.  The user must be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++listed in the default ACL for an object with that type and name, and the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++object will be created with that default ACL set as the object owner.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item check <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Check whether an object of type <type> and name <name> already exists.  If
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++it does, prints C<yes>; if not, prints C<no>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item comment <type> <name> [<comment>]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If <comment> is not given, displays the current comment for the object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++identified by <type> and <name>, or C<No comment set> if none is set.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If <comment> is given, sets the comment on the object identified by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<type> and <name> to <comment>.  If <comment> is the empty string, clears
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the comment.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item create <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Create a new object of type <type> with name <name>.  With some backends,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++this will trigger creation of an entry in an external system as well.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The new object will have no ACLs and no owner set, so usually the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++administrator will want to then set an owner with C<owner> so that the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++object will be usable.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item destroy <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Destroy the object identified by <type> and <name>.  With some backends,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++this will trigger destruction of an object in an external system as well.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item expires <type> <name> [<date> [<time>]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If <date> is not given, displays the current expiration of the object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++identified by <type> and <name>, or C<No expiration set> if none is set.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The expiration will be displayed in seconds since epoch.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If <date> is given, sets the expiration on the object identified by <type>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and <name> to <date> and (if given) <time>.  <date> and <time> must be in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++some format that can be parsed by the Perl Date::Parse module.  Most
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++common formats are supported; if in doubt, use C<YYYY-MM-DD HH:MM:SS>.  If
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<date> is the empty string, clears the expiration of the object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Currently, the expiration of an object is not used.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item flag clear <type> <name> <flag>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Clears the flag <flag> on the object identified by <type> and <name>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item flag set <type> <name> <flag>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Sets the flag <flag> on the object identified by <type> and <name>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Recognized flags are C<locked>, which prevents all further actions on that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++object until the flag is cleared, and C<unchanging>, which tells the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++object backend to not generate new data on get but instead return the same
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++data as previously returned.  The C<unchanging> flag is not meaningful for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++objects that do not generate new data on the fly.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item get <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Prints to standard output the data associated with the object identified
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++by <type> and <name>.  This may trigger generation of new data and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++invalidate old data for that object depending on the object type.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item getacl <type> <name> <acl>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Prints the ACL <acl>, which must be one of C<get>, C<store>, C<show>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<destroy>, or C<flags>, for the object identified by <type> and <name>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Prints C<No ACL set> if that ACL isn't set on that object.  Remember that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++if the C<get>, C<store>, or C<show> ACLs aren't set, authorization falls
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++back to checking the owner ACL.  See the C<owner> command for displaying
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++or setting it.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item getattr <type> <name> <attr>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Prints the object attribute <attr> for the object identified by <type> and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<name>.  Attributes are used to store backend-specific information for a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++particular object type, and <attr> must be an attribute type known to the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++underlying object implementation.  The attribute values, if any, are
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++printed one per line.  If the attribute is not set on this object, nothing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++is printed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item history <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Displays the history for the object identified by <type> and <name>.  This
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++human-readable output will have two lines for each action that changes the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++object, plus for any get action.  The first line has the timestamp of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++action and the action, and the second line gives the user who performed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the action and the host from which they performed it.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item owner <type> <name> [<owner>]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If <owner> is not given, displays the current owner ACL of the object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++identified by <type> and <name>, or C<No owner set> if none is set.  The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++result will be the name of an ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If <owner> is given, sets the owner of the object identified by <type> and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<name> to <owner>.  If <owner> is the empty string, clears the owner of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item rename <type> <name> <new-name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Renames an existing object.  This currently only supports file objects,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++where it renames the object itself, then the name and location of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++object in the file store.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item setacl <type> <name> <acl> <id>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Sets the ACL <acl>, which must be one of C<get>, C<store>, C<show>,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<destroy>, or C<flags>, to <id> on the object identified by <type> and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<name>.  If <id> is the empty string, clears that ACL on the object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item setattr <type> <name> <attr> <value> [<value> ...]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Sets the object attribute <attr> for the object identified by <type> and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<name>.  Attributes are used to store backend-specific information for a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++particular object type, and <attr> must be an attribute type known to the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++underlying object implementation.  To clear the attribute for this object,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++pass in a <value> of the empty string (C<''>).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item show <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Displays the current object metadata for the object identified by <type>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and <name>.  This human-readable output will show the object type and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++name, the owner, any specific ACLs set on the object, the expiration if
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++any, and the user, remote host, and time when the object was created, last
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++stored, and last downloaded.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item store <type> <name> [<data>]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Stores <data> for the object identified by <type> and <name> for later
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++retrieval with C<get>.  Not all object types support this.  If <data> is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++not given as an argument, it will be read from standard input.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item update <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Prints to standard output the data associated with the object identified
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++by <type> and <name>.  If the object is one that can have changing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++information, such as a keytab or password, then we generate new data for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++that object regardless of whether there is current data or the unchanging
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++flag is set.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 ATTRIBUTES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Object attributes store additional properties and configuration
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++information for objects stored in the wallet.  They are displayed as part
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++of the object data with C<show>, retrieved with C<getattr>, and set with
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++C<setattr>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head2 Keytab Attributes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Keytab objects support the following attributes:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item enctypes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Restricts the generated keytab to a specific set of encryption types.  The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++values of this attribute must be enctype strings recognized by Kerberos
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++(strings like C<aes256-cts-hmac-sha1-96> or C<des-cbc-crc>).  Note that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the salt should not be included; since the salt is irrelevant for keytab
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++keys, it will always be set to C<normal> by the wallet.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If this attribute is set, the specified enctype list will be passed to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ktadd when get() is called for that keytab.  If it is not set, the default
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++set in the KDC will be used.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++This attribute is ignored if the C<unchanging> flag is set on a keytab.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Keytabs retrieved with C<unchanging> set will contain all keys present in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the KDC for that Kerberos principal and therefore may contain different
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++enctypes than those requested by this attribute.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 AUTHOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Russ Allbery <eagle@eyrie.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 COPYRIGHT AND LICENSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Copyright 2007, 2008, 2010, 2011, 2012, 2013 The Board of Trustees of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Leland Stanford Junior University
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Permission is hereby granted, free of charge, to any person obtaining a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++copy of this software and associated documentation files (the "Software"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++to deal in the Software without restriction, including without limitation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the rights to use, copy, modify, merge, publish, distribute, sublicense,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and/or sell copies of the Software, and to permit persons to whom the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Software is furnished to do so, subject to the following conditions:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The above copyright notice and this permission notice shall be included in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++all copies or substantial portions of the Software.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++DEALINGS IN THE SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 SEE ALSO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Wallet::Server(3), remctld(8)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++This program is part of the wallet system.  The current version is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++available from L<http://www.eyrie.org/~eagle/software/wallet/>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=cut
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-rename-server-wallet-report.diff b/net/wallet/files/patch-rename-server-wallet-report.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..d1c6916
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-rename-server-wallet-report.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,726 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- server/wallet-report   2016-01-17 19:13:02.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ /dev/null      2016-01-23 14:00:27.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1,360 +0,0 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#!/usr/bin/perl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Wallet server reporting interface.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use 5.008;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use strict;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use warnings;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-use Wallet::Report;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# The help output, sent in reply to the help command.  Lists each supported
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# report command with a brief description of what it does.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-our $HELP = <<'EOH';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Wallet reporting help:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  acls                          All ACLs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  acls duplicate                ACLs that duplicate another
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  acls empty                    All empty ACLs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  acls entry <scheme> <id>      ACLs containing this entry (wildcarded)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  acls nesting <acl>            ACLs containing this ACL as a nested entry
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  acls unused                   ACLs that are not referenced by any object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  audit acls name               ACLs failing the naming policy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  audit objects name            Objects failing the naming policy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  objects                       All objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  objects acl <acl>             Objects granting permissions to that ACL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  objects flag <flag>           Objects with that flag set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  objects history               History of all objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  objects host <hostname>       All host-based objects for a specific host
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  objects owner <owner>         Objects owned by that owner
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  objects type <type>           Objects of that type
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  objects unused                Objects that have never been gotten
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  objects unstored              Objects that have never been stored
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  owners <type> <name>          All ACL entries owning matching objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  schemes                       All configured ACL schemes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  types                         All configured wallet types
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-EOH
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Implementation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Parse and execute a command.  We wrap this in a subroutine call for easier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# testing.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-sub command {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    die "Usage: wallet-report <command> [<args> ...]\n" unless @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my $report = Wallet::Report->new;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    # Parse command-line options and dispatch to the appropriate calls.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    my ($command, @args) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if ($command eq 'acls') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too many arguments to acls\n" if @args > 3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my @acls = $report->acls (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (!@acls and $report->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            die $report->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (@args && $args[0] eq 'duplicate') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            for my $group (@acls) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print join (' ', @$group), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            for my $acl (sort { $$a[1] cmp $$b[1] } @acls) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print "$$acl[1] (ACL ID: $$acl[0])\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'audit') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too many arguments to audit\n" if @args > 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too few arguments to audit\n" if @args < 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my @result = $report->audit (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (!@result and $report->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            die $report->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        for my $item (@result) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            if ($args[0] eq 'acls') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print "$$item[1] (ACL ID: $$item[0])\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                print join (' ', @$item), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'help') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        print $HELP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'objects') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too many arguments to objects\n" if @args > 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my @objects;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (@args && $args[0] eq 'history') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            @objects = $report->objects_history (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } elsif (@args && $args[0] eq 'host') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            @objects = $report->objects_hostname (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            @objects = $report->objects (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (!@objects and $report->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            die $report->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        for my $object (@objects) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print join (' ', @$object), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'owners') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too many arguments to owners\n" if @args > 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too few arguments to owners\n" if @args < 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my @entries = $report->owners (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (!@entries and $report->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            die $report->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        for my $entry (@entries) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print join (' ', @$entry), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'schemes') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too many arguments to schemes\n" if @args > 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my @schemes = $report->acl_schemes;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        for my $entry (@schemes) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print join (' ', @$entry), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } elsif ($command eq 'types') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "too many arguments to types\n" if @args > 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        my @types = $report->types;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        for my $entry (@types) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            print join (' ', @$entry), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die "unknown command $command\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-command (@ARGV);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-__END__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# Documentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 NAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-wallet-report - Wallet server reporting interface
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=for stopwords
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-metadata ACL hostname backend acl acls wildcard SQL Allbery remctl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-MERCHANTABILITY NONINFRINGEMENT sublicense unstored
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 SYNOPSIS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<wallet-report> I<type> [I<args> ...]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 DESCRIPTION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<wallet-report> provides a command-line interface for running reports on
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the wallet database.  It is intended to be run on the wallet server as a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-user with access to the wallet database and configuration, but can also be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-made available via remctl to users who should have reporting privileges.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-This program is a fairly thin wrapper around Wallet::Report that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-translates command strings into method calls and returns the results.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 OPTIONS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-B<wallet-report> takes no traditional options.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 COMMANDS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acls
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acls duplicate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acls empty
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acls entry <scheme> <identifier>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acls unused
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns a list of ACLs in the database.  Except for the C<duplicate>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-report, ACLs will be listed in the form:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    <name> (ACL ID: <id>)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-where <name> is the human-readable name and <id> is the numeric ID.  The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-numeric ID is what's used internally by the wallet system.  There will be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-one line per ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-For the C<duplicate> report, the output will instead be one duplicate set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-per line.  This will be a set of ACLs that all have the same entries.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Only the names will be given, separated by spaces.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If no search type is given, all the ACLs in the database will be returned.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If a search type (and possible search arguments) are given, then the ACLs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-will be limited to those that match the search.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The currently supported ACL search types are:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acls duplicate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all sets of ACLs that are duplicates, meaning that they contain
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-exactly the same entries.  Each line will be the names of the ACLs in a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-set of duplicates, separated by spaces.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acls empty
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all ACLs which have no entries, generally so that abandoned ACLs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-can be destroyed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acls entry <scheme> <identifier>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all ACLs containing an entry with given scheme and identifier.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The scheme must be an exact match, but the <identifier> string will match
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-any identifier containing that string.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acls nested <acl>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all ACLs that contain this ACL as a nested entry.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item acls unused
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all ACLs that are not referenced by any of the objects in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-wallet database, either as an owner or on one of the more specific ACLs.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item audit acls name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item audit objects name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all ACLs or objects that violate the current site naming policy.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Objects will be listed in the form:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and ACLs in the form:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    <name> (ACL ID: <id>)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-where <name> is the human-readable name and <id> is the numeric ID.  The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-numeric ID is what's used internally by the wallet system.  There will be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-one line per object or ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item help
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Displays a summary of all available commands.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects acl <acl>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects flag <flag>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects owner <owner>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects type <type>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects unused
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects unstored
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns a list of objects in the database.  Objects will be listed in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-form:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-There will be one line per object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If no search type is given, all objects in the database will be returned.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-If a search type (and possible search arguments) are given, the objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-will be limited to those that match the search.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The currently supported object search types are:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects acl <acl>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all objects for which the given ACL name or ID has any
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-permissions.  This includes those objects owned by the ACL as well as
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-those where that ACL has any other, more limited permissions.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects flag <flag>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all objects which have the given flag set.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects host <hostname>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all objects that belong to the given host.  This requires adding
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-local configuration to identify objects that belong to a given host.  See
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-L<Wallet::Config/"OBJECT HOST-BASED NAMES"> for more information.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects owner <acl>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all objects owned by the given ACL name or ID.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects type <type>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all objects of the given type.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item objects unused
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns all objects that have never been downloaded (have never been the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-target of a get command).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item owners <type-pattern> <name-pattern>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns a list of all ACL entries in owner ACLs for all objects matching
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-both <type-pattern> and <name-pattern>.  These can be the type or name of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-objects or they can be patterns using C<%> as the wildcard character
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-following the normal rules of SQL patterns.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The output will be one line per ACL line in the form:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    <scheme> <identifier>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-with duplicates suppressed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item schemes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns a list of all registered ACL schemes.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=item types
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Returns a list of all registered object types.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 AUTHOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Russ Allbery <eagle@eyrie.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 COPYRIGHT AND LICENSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Copyright 2016 Russ Allbery <eagle@eyrie.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Copyright 2008, 2009, 2010, 2013, 2015 The Board of Trustees of the Leland
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Stanford Junior University
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Permission is hereby granted, free of charge, to any person obtaining a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-copy of this software and associated documentation files (the "Software"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-to deal in the Software without restriction, including without limitation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-the rights to use, copy, modify, merge, publish, distribute, sublicense,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-and/or sell copies of the Software, and to permit persons to whom the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Software is furnished to do so, subject to the following conditions:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-The above copyright notice and this permission notice shall be included in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-all copies or substantial portions of the Software.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-DEALINGS IN THE SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=head1 SEE ALSO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-Wallet::Config(3), Wallet::Report(3), wallet-backend(8)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-This program is part of the wallet system.  The current version is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-available from L<http://www.eyrie.org/~eagle/software/wallet/>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-=cut
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null      2016-01-23 14:00:27.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ server/wallet-report.in        2016-01-17 19:13:02.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,360 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#!@PERL@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Wallet server reporting interface.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use 5.008;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use strict;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use warnings;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++use Wallet::Report;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# The help output, sent in reply to the help command.  Lists each supported
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# report command with a brief description of what it does.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++our $HELP = <<'EOH';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Wallet reporting help:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  acls                          All ACLs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  acls duplicate                ACLs that duplicate another
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  acls empty                    All empty ACLs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  acls entry <scheme> <id>      ACLs containing this entry (wildcarded)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  acls nesting <acl>            ACLs containing this ACL as a nested entry
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  acls unused                   ACLs that are not referenced by any object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  audit acls name               ACLs failing the naming policy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  audit objects name            Objects failing the naming policy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  objects                       All objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  objects acl <acl>             Objects granting permissions to that ACL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  objects flag <flag>           Objects with that flag set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  objects history               History of all objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  objects host <hostname>       All host-based objects for a specific host
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  objects owner <owner>         Objects owned by that owner
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  objects type <type>           Objects of that type
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  objects unused                Objects that have never been gotten
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  objects unstored              Objects that have never been stored
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  owners <type> <name>          All ACL entries owning matching objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  schemes                       All configured ACL schemes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  types                         All configured wallet types
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++EOH
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Implementation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Parse and execute a command.  We wrap this in a subroutine call for easier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# testing.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++sub command {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    die "Usage: wallet-report <command> [<args> ...]\n" unless @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my $report = Wallet::Report->new;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    # Parse command-line options and dispatch to the appropriate calls.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    my ($command, @args) = @_;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if ($command eq 'acls') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too many arguments to acls\n" if @args > 3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my @acls = $report->acls (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (!@acls and $report->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            die $report->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (@args && $args[0] eq 'duplicate') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            for my $group (@acls) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print join (' ', @$group), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            for my $acl (sort { $$a[1] cmp $$b[1] } @acls) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print "$$acl[1] (ACL ID: $$acl[0])\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'audit') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too many arguments to audit\n" if @args > 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too few arguments to audit\n" if @args < 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my @result = $report->audit (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (!@result and $report->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            die $report->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        for my $item (@result) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            if ($args[0] eq 'acls') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print "$$item[1] (ACL ID: $$item[0])\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                print join (' ', @$item), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'help') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        print $HELP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'objects') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too many arguments to objects\n" if @args > 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my @objects;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (@args && $args[0] eq 'history') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            @objects = $report->objects_history (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } elsif (@args && $args[0] eq 'host') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            @objects = $report->objects_hostname (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            @objects = $report->objects (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (!@objects and $report->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            die $report->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        for my $object (@objects) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print join (' ', @$object), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'owners') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too many arguments to owners\n" if @args > 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too few arguments to owners\n" if @args < 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my @entries = $report->owners (@args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (!@entries and $report->error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            die $report->error, "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        for my $entry (@entries) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print join (' ', @$entry), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'schemes') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too many arguments to schemes\n" if @args > 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my @schemes = $report->acl_schemes;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        for my $entry (@schemes) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print join (' ', @$entry), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } elsif ($command eq 'types') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "too many arguments to types\n" if @args > 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        my @types = $report->types;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        for my $entry (@types) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            print join (' ', @$entry), "\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die "unknown command $command\n";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++command (@ARGV);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++__END__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Documentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++##############################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 NAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++wallet-report - Wallet server reporting interface
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=for stopwords
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++metadata ACL hostname backend acl acls wildcard SQL Allbery remctl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++MERCHANTABILITY NONINFRINGEMENT sublicense unstored
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 SYNOPSIS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<wallet-report> I<type> [I<args> ...]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 DESCRIPTION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<wallet-report> provides a command-line interface for running reports on
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the wallet database.  It is intended to be run on the wallet server as a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++user with access to the wallet database and configuration, but can also be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++made available via remctl to users who should have reporting privileges.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++This program is a fairly thin wrapper around Wallet::Report that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++translates command strings into method calls and returns the results.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 OPTIONS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++B<wallet-report> takes no traditional options.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 COMMANDS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acls
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acls duplicate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acls empty
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acls entry <scheme> <identifier>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acls unused
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns a list of ACLs in the database.  Except for the C<duplicate>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++report, ACLs will be listed in the form:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    <name> (ACL ID: <id>)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++where <name> is the human-readable name and <id> is the numeric ID.  The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++numeric ID is what's used internally by the wallet system.  There will be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++one line per ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++For the C<duplicate> report, the output will instead be one duplicate set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++per line.  This will be a set of ACLs that all have the same entries.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Only the names will be given, separated by spaces.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If no search type is given, all the ACLs in the database will be returned.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If a search type (and possible search arguments) are given, then the ACLs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++will be limited to those that match the search.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The currently supported ACL search types are:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acls duplicate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all sets of ACLs that are duplicates, meaning that they contain
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++exactly the same entries.  Each line will be the names of the ACLs in a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++set of duplicates, separated by spaces.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acls empty
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all ACLs which have no entries, generally so that abandoned ACLs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++can be destroyed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acls entry <scheme> <identifier>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all ACLs containing an entry with given scheme and identifier.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The scheme must be an exact match, but the <identifier> string will match
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++any identifier containing that string.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acls nested <acl>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all ACLs that contain this ACL as a nested entry.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item acls unused
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all ACLs that are not referenced by any of the objects in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++wallet database, either as an owner or on one of the more specific ACLs.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item audit acls name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item audit objects name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all ACLs or objects that violate the current site naming policy.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Objects will be listed in the form:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and ACLs in the form:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    <name> (ACL ID: <id>)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++where <name> is the human-readable name and <id> is the numeric ID.  The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++numeric ID is what's used internally by the wallet system.  There will be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++one line per object or ACL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item help
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Displays a summary of all available commands.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects acl <acl>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects flag <flag>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects owner <owner>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects type <type>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects unused
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects unstored
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns a list of objects in the database.  Objects will be listed in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++form:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    <type> <name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++There will be one line per object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If no search type is given, all objects in the database will be returned.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++If a search type (and possible search arguments) are given, the objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++will be limited to those that match the search.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The currently supported object search types are:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=over 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects acl <acl>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all objects for which the given ACL name or ID has any
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++permissions.  This includes those objects owned by the ACL as well as
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++those where that ACL has any other, more limited permissions.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects flag <flag>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all objects which have the given flag set.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects host <hostname>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all objects that belong to the given host.  This requires adding
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++local configuration to identify objects that belong to a given host.  See
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++L<Wallet::Config/"OBJECT HOST-BASED NAMES"> for more information.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects owner <acl>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all objects owned by the given ACL name or ID.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects type <type>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all objects of the given type.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item objects unused
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns all objects that have never been downloaded (have never been the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++target of a get command).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item owners <type-pattern> <name-pattern>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns a list of all ACL entries in owner ACLs for all objects matching
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++both <type-pattern> and <name-pattern>.  These can be the type or name of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++objects or they can be patterns using C<%> as the wildcard character
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++following the normal rules of SQL patterns.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The output will be one line per ACL line in the form:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    <scheme> <identifier>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++with duplicates suppressed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item schemes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns a list of all registered ACL schemes.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=item types
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Returns a list of all registered object types.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=back
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 AUTHOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Russ Allbery <eagle@eyrie.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 COPYRIGHT AND LICENSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Copyright 2016 Russ Allbery <eagle@eyrie.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Copyright 2008, 2009, 2010, 2013, 2015 The Board of Trustees of the Leland
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Stanford Junior University
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Permission is hereby granted, free of charge, to any person obtaining a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++copy of this software and associated documentation files (the "Software"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++to deal in the Software without restriction, including without limitation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++the rights to use, copy, modify, merge, publish, distribute, sublicense,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++and/or sell copies of the Software, and to permit persons to whom the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Software is furnished to do so, subject to the following conditions:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++The above copyright notice and this permission notice shall be included in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++all copies or substantial portions of the Software.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++DEALINGS IN THE SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=head1 SEE ALSO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Wallet::Config(3), Wallet::Report(3), wallet-backend(8)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++This program is part of the wallet system.  The current version is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++available from L<http://www.eyrie.org/~eagle/software/wallet/>.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++=cut
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-tests-client-full-t.in.diff b/net/wallet/files/patch-tests-client-full-t.in.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..9d0cada
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-tests-client-full-t.in.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,9 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- tests/client/full-t.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ tests/client/full-t.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1,4 +1,5 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#!/usr/bin/perl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#!@PERL@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# -*- perl -*-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # End-to-end tests for the wallet client.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/net/wallet/files/patch-tests-client-prompt-t.in.diff b/net/wallet/files/patch-tests-client-prompt-t.in.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..21a10bc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/net/wallet/files/patch-tests-client-prompt-t.in.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,9 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- tests/client/prompt-t.in.orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ tests/client/prompt-t.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1,4 +1,5 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#!/usr/bin/perl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#!@PERL@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# -*- perl -*-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Password prompting tests for the wallet client.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #
</span></pre><pre style='margin:0'>

</pre>