From 7023eed166e2bf7ec70764d3af9806f7793961e2 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Sun, 17 Jan 2016 20:54:20 -0800 Subject: Update the minimum Perl version in the README --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 9dcd711..d19bc92 100644 --- a/README +++ b/README @@ -65,7 +65,7 @@ REQUIREMENTS The wallet client will build with either MIT Kerberos or Heimdal. - The wallet server is written in Perl and requires Perl 5.6.0 or later + The wallet server is written in Perl and requires Perl 5.8.0 or later plus Module::Build to build. It uses DBIx::Class and DBI to talk to a database, and therefore the DBIx::Class and DBI modules (and their dependencies) and a DBD module for the database it will use must be -- cgit v1.2.3 From 9db57ec57cf7bcc46c986c1bc67eb3fe41b7d08b Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Sun, 17 Jan 2016 20:55:27 -0800 Subject: Fix typo in README --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index d19bc92..8b06aab 100644 --- a/README +++ b/README @@ -92,7 +92,7 @@ REQUIREMENTS on CPAN for older versions. The keytab support in the wallet server supports either Heimdal or MIT - Kerberos KDCs and has exeprimental support for Active Directory. The + Kerberos KDCs and has experimental support for Active Directory. The Heimdal support requires the Heimdal::Kadm5 Perl module. The MIT Kerberos support requires the MIT Kerberos kadmin client program be installed. The Active Directory support requires the Net::LDAP, -- cgit v1.2.3 From d06e318c304a8c55277c616765a8a0502eb9207d Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Sat, 23 Jan 2016 14:49:52 -0800 Subject: Remove dead strlcpy and strlcat declarations Remove stray references to strlcpy and strlcat that broke builds on platforms where those functions are part of libc. Thanks to Karl Kornel for the report. --- NEWS | 6 ++++++ portable/system.h | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index e299bc1..453c326 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,11 @@ User-Visible wallet Changes +wallet 1.4 (unreleased) + + Remove stray references to strlcpy and strlcat that broke builds on + platforms where those functions are part of libc. Thanks to Karl + Kornel for the report. + wallet 1.3 (2016-01-17) This release adds initial, experimental support for using Active diff --git a/portable/system.h b/portable/system.h index 581e46c..f683300 100644 --- a/portable/system.h +++ b/portable/system.h @@ -136,12 +136,6 @@ extern void *reallocarray(void *, size_t, size_t); #if !HAVE_SETENV extern int setenv(const char *, const char *, int); #endif -#if !HAVE_DECL_STRLCAT -extern size_t strlcat(char *, const char *, size_t); -#endif -#if !HAVE_DECL_STRLCPY -extern size_t strlcpy(char *, const char *, size_t); -#endif /* Undo default visibility change. */ #pragma GCC visibility pop -- cgit v1.2.3 From 61a42ce222ed07da0c22a5394e5f3b59cc4bf690 Mon Sep 17 00:00:00 2001 From: "A. Karl Kornel" Date: Fri, 22 Jan 2016 22:19:45 -0800 Subject: Make Perl path configurable & check version Use configure to determine the path to Perl, and error out if Perl is not found or is too old. This also means users can set a path to a custom or weirdly-named Perl binary. --- Makefile.am | 2 +- configure.ac | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 6cabc93..87ba959 100644 --- a/Makefile.am +++ b/Makefile.am @@ -236,7 +236,7 @@ perl/blib/lib/Wallet/Config.pm: $(srcdir)/perl/lib/Wallet/Config.pm $(INSTALL_DATA) $(srcdir)/tests/tap/perl/Test/RRA.pm perl/t/lib/Test/ $(INSTALL_DATA) $(srcdir)/tests/tap/perl/Test/RRA/Config.pm \ perl/t/lib/Test/RRA/ - cd perl && perl Build.PL $(WALLET_PERL_FLAGS) + cd perl && $(PERL) Build.PL $(WALLET_PERL_FLAGS) cd perl && ./Build # This is a really ugly hack to only honor prefix when running make install diff --git a/configure.ac b/configure.ac index 4f56eb0..350132a 100644 --- a/configure.ac +++ b/configure.ac @@ -79,6 +79,15 @@ AS_IF([test x"$REMCTLD" != x], [AC_DEFINE_UNQUOTED([PATH_REMCTLD], ["$REMCTLD"], [Define to the full path to remctld to run remctl tests.])]) +AC_ARG_VAR(PERL, [Path to the Perl binary]) +AC_PATH_PROG(PERL, perl) +if test -z "$PERL"; then + AC_MSG_ERROR([Could not find Perl.]) +fi +$PERL -e 'require 5.008;' || { + AC_MSG_ERROR([Perl 5.8 or better is required.]) +} + dnl Enable appropriate warnings. AM_CONDITIONAL([WARNINGS_GCC], [test x"$GCC" = xyes && test x"$CLANG" != xyes]) AM_CONDITIONAL([WARNINGS_CLANG], [test x"$CLANG" = xyes]) -- cgit v1.2.3 From 67d9e9a278171ea7cd0e9e2c5b754a50887d4752 Mon Sep 17 00:00:00 2001 From: "A. Karl Kornel" Date: Fri, 22 Jan 2016 23:36:04 -0800 Subject: Customize the path to Perl in the server scripts The server scripts now have a unique string where the Perl path should be, and the Makefile uses sed to insert the correct path at build time (using the path determined by configure). The server scripts now have .in extensions, and setting the executable flag is handled by the Makefile. We also have to change autogen, because it looks for the scripts in the server directory when it generates the man pages. --- Makefile.am | 8 +- autogen | 13 +- server/keytab-backend | 245 ----------------- server/keytab-backend.in | 245 +++++++++++++++++ server/wallet-admin | 175 ------------ server/wallet-admin.in | 175 ++++++++++++ server/wallet-backend | 695 ----------------------------------------------- server/wallet-backend.in | 695 +++++++++++++++++++++++++++++++++++++++++++++++ server/wallet-report | 360 ------------------------ server/wallet-report.in | 360 ++++++++++++++++++++++++ 10 files changed, 1491 insertions(+), 1480 deletions(-) delete mode 100755 server/keytab-backend create mode 100644 server/keytab-backend.in delete mode 100755 server/wallet-admin create mode 100644 server/wallet-admin.in delete mode 100755 server/wallet-backend create mode 100644 server/wallet-backend.in delete mode 100755 server/wallet-report create mode 100644 server/wallet-report.in diff --git a/Makefile.am b/Makefile.am index 87ba959..3e76885 100644 --- a/Makefile.am +++ b/Makefile.am @@ -210,13 +210,19 @@ warnings: # Remove some additional files. CLEANFILES = perl/t/lib/Test/RRA.pm perl/t/lib/Test/RRA/Automake.pm \ - perl/t/lib/Test/RRA/Config.pm + perl/t/lib/Test/RRA/Config.pm $(dist_sbin_SCRIPTS) MAINTAINERCLEANFILES = Makefile.in aclocal.m4 build-aux/compile \ build-aux/depcomp build-aux/install-sh build-aux/missing \ client/wallet.1 config.h.in config.h.in~ configure \ contrib/wallet-report.8 server/keytab-backend.8 \ server/wallet-admin.8 server/wallet-backend.8 server/wallet-report.8 +# For each of the perl scripts in server/, we need to fill in the path to the +# Perl binary that was located during configuration. +$(dist_sbin_SCRIPTS): + sed 's|WALLET_PERL_PATH|$(PERL)|' < $(srcdir)/$@.in > $(srcdir)/$@ + chmod a+x $(srcdir)/$@ + # Take appropriate actions in the Perl directory as well. We don't want to # always build the Perl directory in all-local, since otherwise Automake does # this for every target, which overrides some hacks we have to do for Debian diff --git a/autogen b/autogen index 3b8bc1b..c725fd9 100755 --- a/autogen +++ b/autogen @@ -13,10 +13,15 @@ for doc in client/wallet client/wallet-rekey ; do pod2man --release="$version" --center=wallet \ --name=`basename "$doc" | tr a-z A-Z` "$doc".pod > "$doc".1 done -for doc in contrib/wallet-rekey-periodic contrib/wallet-summary \ - contrib/wallet-unknown-hosts server/keytab-backend \ - server/wallet-admin server/wallet-backend \ - server/wallet-report ; do +for doc in contrib/wallet-rekey-periodic contrib/wallet-summary \ + contrib/wallet-unknown-hosts ; do pod2man --release="$version" --center=wallet --section=8 \ --name=`basename "$doc" | tr a-z A-Z` "$doc" > "$doc".8 done +for doc in server/keytab-backend server/wallet-admin \ + server/wallet-admin server/wallet-backend \ + server/wallet-report ; do + pod2man --release="$version" --center=wallet --section=8 \ + --name=`basename "$doc" | tr a-z A-Z` "$doc.in" > "$doc".8 +done + diff --git a/server/keytab-backend b/server/keytab-backend deleted file mode 100755 index 6e47331..0000000 --- a/server/keytab-backend +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/perl -# -# Extract keytabs from the KDC without changing the key. -# -# This is a remctl backend that extracts existing keys from a KDC database -# using kadmin.local. It requires a patched version of kadmin.local that -# supports the -norandkey option. It expects a configuration file in -# /etc/krb5kdc/allow-extract that contains a list of regexes, one per line, -# matching principals that may be extracted in this fashion. (Generally you -# do not want to list user principals here.) It also expects to be able to -# write to a directory named /var/lib/keytabs; that's where it puts the -# keytabs temporarily before sending them back to via remctl. -# -# remctl should handle authorization restrictions on this script. It doesn't -# do any additional authorization checks itself. -# -# The keytab for the extracted principal will be printed to standard output. - -use 5.008; -use strict; -use warnings; - -use Sys::Syslog qw(openlog syslog); - -# Path to configuration file listing principals that may be extracted. -our $CONFIG = '/etc/krb5kdc/allow-extract'; - -# The full path to a kadmin.local that supports -norandkey. -our $KADMIN = '/usr/sbin/kadmin.local'; - -# A temporary area into which keytabs should be written. -our $TMP = '/var/lib/keytabs'; - -# Set to zero to suppress syslog logging, which is used only for testing. Set -# to a reference to a string to append messages to that string instead. -our $SYSLOG; -$SYSLOG = 1 unless defined $SYSLOG; - -############################################################################## -# Logging -############################################################################## - -# Initialize logging. -sub log_init { - if (ref $SYSLOG) { - $$SYSLOG = ''; - } elsif ($SYSLOG) { - openlog ('keytab-backend', 'pid', 'auth'); - } -} - -# Log a failure message to both syslog and to stderr and exit with a non-zero -# status. -sub error { - my $message = join ('', @_); - if (ref $SYSLOG) { - $$SYSLOG .= $message . "\n"; - } elsif ($SYSLOG) { - syslog ('err', '%s', $message); - } - die "keytab-backend: $message\n"; -} - -# Log a regular message, generally for success. -sub info { - my $message = join ('', @_); - if (ref $SYSLOG) { - $$SYSLOG .= $message . "\n"; - } elsif ($SYSLOG) { - syslog ('info', '%s', $message); - } -} - -############################################################################## -# Implementation -############################################################################## - -# Check and download the keytab. This is in a subroutine call for easier -# testing. We separately log actions unless $SYSLOG is set to 0. remctld -# keeps some logs, but it won't tell us whether the download is successful or -# not. -sub download { - my (@args) = @_; - log_init; - - # Set up a default identity if run from the command line. - $ENV{REMOTE_USER} = getpwnam ($<) || 'UNKNOWN' unless $ENV{REMOTE_USER}; - - # Read the regexes of valid principals into memory. - open (CONFIG, '<', $CONFIG) or error "cannot open $CONFIG: $!"; - my @valid; - while () { - next if /^\s*\#/; - next if /^\s*$/; - s/^\s+//; - s/\s+$//; - s/\s*\#.*//; - push (@valid, qr/$_/); - } - close CONFIG; - - # The first argument will be the remctl service, so skip it. - if (@args == 2) { - shift @args; - } - if (@args != 1) { - error "invalid arguments: @args"; - } - my $principal = $args[0]; - - # Ensure that we're allowed to retrieve this principal. - unless ($principal =~ m%^[\w-]+(?:/[\w.-]+)?\@[\w.-]+\z%) { - error "bad principal name $principal"; - } - my $okay; - for my $regex (@valid) { - if ($principal =~ /$regex/) { - $okay = 1; - last; - } - } - unless ($okay) { - error "permission denied: $ENV{REMOTE_USER} may not retrieve" - . " $principal"; - } - - # Do the actual work. - my $filename = "$TMP/keytab$$"; - my $command = "ktadd -k $filename -q -norandkey $principal"; - my $output = `$KADMIN -q '$command' 2>&1`; - if ($? != 0) { - my $status = ($? >> 8); - warn $output; - error "retrieve of $principal failed for $ENV{REMOTE_USER}:" - . " kadmin.local exited with status $status"; - } - open (KEYTAB, '<', $filename) - or error "cannot open temporary keytab $filename: $!"; - print while ; - close KEYTAB; - unlink $filename; - info ("keytab $principal retrieved by $ENV{REMOTE_USER}"); -} -download (@ARGV); -__END__ - -############################################################################## -# Documentation -############################################################################## - -=for stopwords -keytab-backend keytabs KDC keytab kadmin.local -norandkey ktadd remctld -auth Allbery rekeying MERCHANTABILITY NONINFRINGEMENT sublicense -kadmin.local. - -=head1 NAME - -keytab-backend - Extract keytabs from the KDC without changing the key - -=head1 SYNOPSIS - -B retrieve I - -=head1 DESCRIPTION - -B retrieves a keytab for an existing principal from the -KDC database without changing the current key. It allows generation of a -keytab for a service without rekeying that service. It requires a -B patched to support the B<-norandkey> option to B. - -This script is intended to run under B. On success, it prints -the keytab to standard output, logs a success message to syslog (facility -auth, priority info), and exits with status 0. On failure, it prints out -an error message, logs an error to syslog (facility auth, priority err), -and exits with a non-zero status. - -The principal is checked for basic sanity (only accepting alphanumerics, -C<_>, and C<-> with an optional instance and then only alphanumerics, -C<_>, C<->, and C<.> in the realm) and then checked against a -configuration file that lists regexes of principals that can be retrieved. -When deploying this software, limit as tightly as possible which -principals can be downloaded in this fashion. Generally only shared -service principals used on multiple systems should be made available in -this way. - -B does not do any authorization checks. Those should be -done by B before it is called. - -=head1 FILES - -=over 4 - -=item F - -The configuration file that controls which principals can have their -keytabs retrieved. Blank lines and lines starting with C<#>, as well as -anything after C<#> on a line, are ignored. All other lines should be -Perl regular expressions, one per line, that match principals whose -keytabs can be retrieved by B. Any principal that does -not match one of those regular expressions cannot be retrieved. - -=item F - -The temporary directory used for creating keytabs. B will -create the keytab in this directory, make sure that was successful, and -then delete the temporary file after the results have been sent to -standard output. - -=back - -=head1 AUTHOR - -Russ Allbery - -=head1 COPYRIGHT AND LICENSE - -Copyright 2006, 2007, 2008, 2010, 2013 The Board of Trustees of the Leland -Stanford Junior University - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -=head1 SEE ALSO - -kadmin.local(8), remctld(8) - -This program is part of the wallet system. The current version is -available from L. - -=cut diff --git a/server/keytab-backend.in b/server/keytab-backend.in new file mode 100644 index 0000000..13cb33e --- /dev/null +++ b/server/keytab-backend.in @@ -0,0 +1,245 @@ +#!WALLET_PERL_PATH +# +# Extract keytabs from the KDC without changing the key. +# +# This is a remctl backend that extracts existing keys from a KDC database +# using kadmin.local. It requires a patched version of kadmin.local that +# supports the -norandkey option. It expects a configuration file in +# /etc/krb5kdc/allow-extract that contains a list of regexes, one per line, +# matching principals that may be extracted in this fashion. (Generally you +# do not want to list user principals here.) It also expects to be able to +# write to a directory named /var/lib/keytabs; that's where it puts the +# keytabs temporarily before sending them back to via remctl. +# +# remctl should handle authorization restrictions on this script. It doesn't +# do any additional authorization checks itself. +# +# The keytab for the extracted principal will be printed to standard output. + +use 5.008; +use strict; +use warnings; + +use Sys::Syslog qw(openlog syslog); + +# Path to configuration file listing principals that may be extracted. +our $CONFIG = '/etc/krb5kdc/allow-extract'; + +# The full path to a kadmin.local that supports -norandkey. +our $KADMIN = '/usr/sbin/kadmin.local'; + +# A temporary area into which keytabs should be written. +our $TMP = '/var/lib/keytabs'; + +# Set to zero to suppress syslog logging, which is used only for testing. Set +# to a reference to a string to append messages to that string instead. +our $SYSLOG; +$SYSLOG = 1 unless defined $SYSLOG; + +############################################################################## +# Logging +############################################################################## + +# Initialize logging. +sub log_init { + if (ref $SYSLOG) { + $$SYSLOG = ''; + } elsif ($SYSLOG) { + openlog ('keytab-backend', 'pid', 'auth'); + } +} + +# Log a failure message to both syslog and to stderr and exit with a non-zero +# status. +sub error { + my $message = join ('', @_); + if (ref $SYSLOG) { + $$SYSLOG .= $message . "\n"; + } elsif ($SYSLOG) { + syslog ('err', '%s', $message); + } + die "keytab-backend: $message\n"; +} + +# Log a regular message, generally for success. +sub info { + my $message = join ('', @_); + if (ref $SYSLOG) { + $$SYSLOG .= $message . "\n"; + } elsif ($SYSLOG) { + syslog ('info', '%s', $message); + } +} + +############################################################################## +# Implementation +############################################################################## + +# Check and download the keytab. This is in a subroutine call for easier +# testing. We separately log actions unless $SYSLOG is set to 0. remctld +# keeps some logs, but it won't tell us whether the download is successful or +# not. +sub download { + my (@args) = @_; + log_init; + + # Set up a default identity if run from the command line. + $ENV{REMOTE_USER} = getpwnam ($<) || 'UNKNOWN' unless $ENV{REMOTE_USER}; + + # Read the regexes of valid principals into memory. + open (CONFIG, '<', $CONFIG) or error "cannot open $CONFIG: $!"; + my @valid; + while () { + next if /^\s*\#/; + next if /^\s*$/; + s/^\s+//; + s/\s+$//; + s/\s*\#.*//; + push (@valid, qr/$_/); + } + close CONFIG; + + # The first argument will be the remctl service, so skip it. + if (@args == 2) { + shift @args; + } + if (@args != 1) { + error "invalid arguments: @args"; + } + my $principal = $args[0]; + + # Ensure that we're allowed to retrieve this principal. + unless ($principal =~ m%^[\w-]+(?:/[\w.-]+)?\@[\w.-]+\z%) { + error "bad principal name $principal"; + } + my $okay; + for my $regex (@valid) { + if ($principal =~ /$regex/) { + $okay = 1; + last; + } + } + unless ($okay) { + error "permission denied: $ENV{REMOTE_USER} may not retrieve" + . " $principal"; + } + + # Do the actual work. + my $filename = "$TMP/keytab$$"; + my $command = "ktadd -k $filename -q -norandkey $principal"; + my $output = `$KADMIN -q '$command' 2>&1`; + if ($? != 0) { + my $status = ($? >> 8); + warn $output; + error "retrieve of $principal failed for $ENV{REMOTE_USER}:" + . " kadmin.local exited with status $status"; + } + open (KEYTAB, '<', $filename) + or error "cannot open temporary keytab $filename: $!"; + print while ; + close KEYTAB; + unlink $filename; + info ("keytab $principal retrieved by $ENV{REMOTE_USER}"); +} +download (@ARGV); +__END__ + +############################################################################## +# Documentation +############################################################################## + +=for stopwords +keytab-backend keytabs KDC keytab kadmin.local -norandkey ktadd remctld +auth Allbery rekeying MERCHANTABILITY NONINFRINGEMENT sublicense +kadmin.local. + +=head1 NAME + +keytab-backend - Extract keytabs from the KDC without changing the key + +=head1 SYNOPSIS + +B retrieve I + +=head1 DESCRIPTION + +B retrieves a keytab for an existing principal from the +KDC database without changing the current key. It allows generation of a +keytab for a service without rekeying that service. It requires a +B patched to support the B<-norandkey> option to B. + +This script is intended to run under B. On success, it prints +the keytab to standard output, logs a success message to syslog (facility +auth, priority info), and exits with status 0. On failure, it prints out +an error message, logs an error to syslog (facility auth, priority err), +and exits with a non-zero status. + +The principal is checked for basic sanity (only accepting alphanumerics, +C<_>, and C<-> with an optional instance and then only alphanumerics, +C<_>, C<->, and C<.> in the realm) and then checked against a +configuration file that lists regexes of principals that can be retrieved. +When deploying this software, limit as tightly as possible which +principals can be downloaded in this fashion. Generally only shared +service principals used on multiple systems should be made available in +this way. + +B does not do any authorization checks. Those should be +done by B before it is called. + +=head1 FILES + +=over 4 + +=item F + +The configuration file that controls which principals can have their +keytabs retrieved. Blank lines and lines starting with C<#>, as well as +anything after C<#> on a line, are ignored. All other lines should be +Perl regular expressions, one per line, that match principals whose +keytabs can be retrieved by B. Any principal that does +not match one of those regular expressions cannot be retrieved. + +=item F + +The temporary directory used for creating keytabs. B will +create the keytab in this directory, make sure that was successful, and +then delete the temporary file after the results have been sent to +standard output. + +=back + +=head1 AUTHOR + +Russ Allbery + +=head1 COPYRIGHT AND LICENSE + +Copyright 2006, 2007, 2008, 2010, 2013 The Board of Trustees of the Leland +Stanford Junior University + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +=head1 SEE ALSO + +kadmin.local(8), remctld(8) + +This program is part of the wallet system. The current version is +available from L. + +=cut diff --git a/server/wallet-admin b/server/wallet-admin deleted file mode 100755 index e74b2f1..0000000 --- a/server/wallet-admin +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/perl -# -# Wallet server administrative commands. - -use 5.008; -use strict; -use warnings; - -use Wallet::Admin; - -############################################################################## -# Implementation -############################################################################## - -# Parse and execute a command. We wrap this in a subroutine call for easier -# testing. -sub command { - die "Usage: wallet-admin [ ...]\n" unless @_; - my $admin = Wallet::Admin->new; - - # Parse command-line options and dispatch to the appropriate calls. - my ($command, @args) = @_; - if ($command eq 'destroy') { - die "too many arguments to destroy\n" if @args; - print 'This will delete all data in the wallet database. Are you' - . ' sure (N/y)? '; - my $response = ; - unless ($response and $response =~ /^y/i) { - die "Aborted\n"; - } - $admin->destroy or die $admin->error, "\n"; - } elsif ($command eq 'initialize') { - die "too many arguments to initialize\n" if @args > 1; - die "too few arguments to initialize\n" if @args < 1; - die "invalid admin principal $args[0]\n" - unless $args[0] =~ /^[^\@\s]+\@\S+$/; - $admin->initialize (@args) or die $admin->error, "\n"; - } elsif ($command eq 'register') { - die "too many arguments to register\n" if @args > 3; - die "too few arguments to register\n" if @args < 3; - my ($object, $type, $class) = @args; - if ($object eq 'object') { - unless ($admin->register_object ($type, $class)) { - die $admin->error, "\n"; - } - } elsif ($object eq 'verifier') { - unless ($admin->register_verifier ($type, $class)) { - die $admin->error, "\n"; - } - } else { - die "only object or verifier is supported for register\n"; - } - } elsif ($command eq 'upgrade') { - die "too many arguments to upgrade\n" if @args; - $admin->upgrade or die $admin->error, "\n"; - } else { - die "unknown command $command\n"; - } -} -command (@ARGV); -__END__ - -############################################################################## -# Documentation -############################################################################## - -=for stopwords -metadata ACL hostname backend acl acls wildcard SQL Allbery verifier -MERCHANTABILITY NONINFRINGEMENT sublicense - -=head1 NAME - -wallet-admin - Wallet server administrative commands - -=head1 SYNOPSIS - -B I [I ...] - -=head1 DESCRIPTION - -B provides a command-line interface for performing -administrative actions for the wallet system, such as setting up a new -database or running reports. It is intended to be run on the wallet -server as a user with access to the wallet database and configuration. - -This program is a fairly thin wrapper around Wallet::Admin that translates -command strings into method calls and returns the results. - -=head1 OPTIONS - -B takes no traditional options. - -=head1 COMMANDS - -=over 4 - -=item destroy - -Deletes all data in the wallet database and drops all of the -wallet-created tables, restoring the database to its state prior to an -C command. Since this command is destructive and cannot be -easily recovered from, B will prompt first to be sure the -user intends to do this. - -=item initialize - -Given an empty database, initializes it for use with the wallet server by -creating the necessary tables and initial metadata. Also creates an ACL -with the name ADMIN, used for administrative privileges to the wallet -system, and adds an ACL entry to it with a scheme of C and an -instance of . This bootstraps the authentication system and -allows that user to make further changes to the ADMIN ACL and the rest of -the wallet database. C uses C as the hostname and - as the user when logging the history of the ADMIN ACL creation -and for any subsequent actions required to initialize the database. - -Before running C, the wallet system has to be configured. See -Wallet::Config(3) for more details. Depending on the database backend -used, the database may also have to be created in advance. - -=item register (object | verifier) - -Registers an implementation of a wallet object or ACL verifier in the -wallet database. The Perl class is registered as the -implementation of an object of type or an ACL verifier of scheme -, allowing creation of objects with that type or ACL lines with that -scheme. - -All object and ACL implementations that come with wallet are registered by -default as part of database initialization, so this command is used -primarily to register local implementations of additional object types or -ACL schemes. - -=item upgrade - -Upgrades the database to the latest schema version, preserving data as -much as possible. - -=back - -=head1 AUTHOR - -Russ Allbery - -=head1 COPYRIGHT AND LICENSE - -Copyright 2008, 2009, 2010, 2011, 2013 The Board of Trustees of the Leland -Stanford Junior University - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -=head1 SEE ALSO - -Wallet::Admin(3), Wallet::Config(3), wallet-backend(8) - -This program is part of the wallet system. The current version is -available from L. - -=cut diff --git a/server/wallet-admin.in b/server/wallet-admin.in new file mode 100644 index 0000000..84141e6 --- /dev/null +++ b/server/wallet-admin.in @@ -0,0 +1,175 @@ +#!WALLET_PERL_PATH +# +# Wallet server administrative commands. + +use 5.008; +use strict; +use warnings; + +use Wallet::Admin; + +############################################################################## +# Implementation +############################################################################## + +# Parse and execute a command. We wrap this in a subroutine call for easier +# testing. +sub command { + die "Usage: wallet-admin [ ...]\n" unless @_; + my $admin = Wallet::Admin->new; + + # Parse command-line options and dispatch to the appropriate calls. + my ($command, @args) = @_; + if ($command eq 'destroy') { + die "too many arguments to destroy\n" if @args; + print 'This will delete all data in the wallet database. Are you' + . ' sure (N/y)? '; + my $response = ; + unless ($response and $response =~ /^y/i) { + die "Aborted\n"; + } + $admin->destroy or die $admin->error, "\n"; + } elsif ($command eq 'initialize') { + die "too many arguments to initialize\n" if @args > 1; + die "too few arguments to initialize\n" if @args < 1; + die "invalid admin principal $args[0]\n" + unless $args[0] =~ /^[^\@\s]+\@\S+$/; + $admin->initialize (@args) or die $admin->error, "\n"; + } elsif ($command eq 'register') { + die "too many arguments to register\n" if @args > 3; + die "too few arguments to register\n" if @args < 3; + my ($object, $type, $class) = @args; + if ($object eq 'object') { + unless ($admin->register_object ($type, $class)) { + die $admin->error, "\n"; + } + } elsif ($object eq 'verifier') { + unless ($admin->register_verifier ($type, $class)) { + die $admin->error, "\n"; + } + } else { + die "only object or verifier is supported for register\n"; + } + } elsif ($command eq 'upgrade') { + die "too many arguments to upgrade\n" if @args; + $admin->upgrade or die $admin->error, "\n"; + } else { + die "unknown command $command\n"; + } +} +command (@ARGV); +__END__ + +############################################################################## +# Documentation +############################################################################## + +=for stopwords +metadata ACL hostname backend acl acls wildcard SQL Allbery verifier +MERCHANTABILITY NONINFRINGEMENT sublicense + +=head1 NAME + +wallet-admin - Wallet server administrative commands + +=head1 SYNOPSIS + +B I [I ...] + +=head1 DESCRIPTION + +B provides a command-line interface for performing +administrative actions for the wallet system, such as setting up a new +database or running reports. It is intended to be run on the wallet +server as a user with access to the wallet database and configuration. + +This program is a fairly thin wrapper around Wallet::Admin that translates +command strings into method calls and returns the results. + +=head1 OPTIONS + +B takes no traditional options. + +=head1 COMMANDS + +=over 4 + +=item destroy + +Deletes all data in the wallet database and drops all of the +wallet-created tables, restoring the database to its state prior to an +C command. Since this command is destructive and cannot be +easily recovered from, B will prompt first to be sure the +user intends to do this. + +=item initialize + +Given an empty database, initializes it for use with the wallet server by +creating the necessary tables and initial metadata. Also creates an ACL +with the name ADMIN, used for administrative privileges to the wallet +system, and adds an ACL entry to it with a scheme of C and an +instance of . This bootstraps the authentication system and +allows that user to make further changes to the ADMIN ACL and the rest of +the wallet database. C uses C as the hostname and + as the user when logging the history of the ADMIN ACL creation +and for any subsequent actions required to initialize the database. + +Before running C, the wallet system has to be configured. See +Wallet::Config(3) for more details. Depending on the database backend +used, the database may also have to be created in advance. + +=item register (object | verifier) + +Registers an implementation of a wallet object or ACL verifier in the +wallet database. The Perl class is registered as the +implementation of an object of type or an ACL verifier of scheme +, allowing creation of objects with that type or ACL lines with that +scheme. + +All object and ACL implementations that come with wallet are registered by +default as part of database initialization, so this command is used +primarily to register local implementations of additional object types or +ACL schemes. + +=item upgrade + +Upgrades the database to the latest schema version, preserving data as +much as possible. + +=back + +=head1 AUTHOR + +Russ Allbery + +=head1 COPYRIGHT AND LICENSE + +Copyright 2008, 2009, 2010, 2011, 2013 The Board of Trustees of the Leland +Stanford Junior University + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +=head1 SEE ALSO + +Wallet::Admin(3), Wallet::Config(3), wallet-backend(8) + +This program is part of the wallet system. The current version is +available from L. + +=cut diff --git a/server/wallet-backend b/server/wallet-backend deleted file mode 100755 index aa83a96..0000000 --- a/server/wallet-backend +++ /dev/null @@ -1,695 +0,0 @@ -#!/usr/bin/perl -# -# Wallet server for storing and retrieving secure data. - -use 5.008; -use strict; -use warnings; - -use Getopt::Long qw(GetOptions); -use Sys::Syslog qw(openlog syslog); -use Wallet::Server; - -# Set to zero to suppress syslog logging, which is used for testing and for -# the -q option. Set to a reference to a string to append messages to that -# string instead. -our $SYSLOG; -$SYSLOG = 1 unless defined $SYSLOG; - -############################################################################## -# Logging -############################################################################## - -# Initialize logging. -sub log_init { - if (ref $SYSLOG) { - $$SYSLOG = ''; - } elsif ($SYSLOG) { - openlog ('wallet-backend', 'pid', 'auth'); - } -} - -# Get an identity string for the user suitable for including in log messages. -sub identity { - my $identity = ''; - if ($ENV{REMOTE_USER}) { - $identity = $ENV{REMOTE_USER}; - my $host = $ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR}; - $identity .= " ($host)" if $host; - } - return $identity; -} - -# Log an error message to both syslog and to stderr and exit with a non-zero -# status. -sub error { - my $message = join ('', @_); - if ($SYSLOG) { - my $identity = identity; - my $log; - if ($identity) { - $log = "error for $identity: $message"; - } else { - $log = "error: $message"; - } - $log =~ s/[^\x20-\x7e]/_/g; - if (ref $SYSLOG) { - $$SYSLOG .= "$log\n"; - } else { - syslog ('err', "%s", $log); - } - } - die "$message\n"; -} - -# Log a wallet failure message for a given command to both syslog and to -# stderr and exit with a non-zero status. Takes the message and the command -# that was being run. -sub failure { - my ($message, @command) = @_; - if ($SYSLOG) { - my $log = "command @command from " . identity . " failed: $message"; - $log =~ s/[^\x20-\x7e]/_/g; - if (ref $SYSLOG) { - $$SYSLOG .= "$log\n"; - } else { - syslog ('err', "%s", $log); - } - } - die "$message\n"; -} - -# Log a wallet success message for a given command. -sub success { - my (@command) = @_; - if ($SYSLOG) { - my $log = "command @command from " . identity . " succeeded"; - $log =~ s/[^\x20-\x7e]/_/g; - if (ref $SYSLOG) { - $$SYSLOG .= "$log\n"; - } else { - syslog ('info', "%s", $log); - } - } -} - -############################################################################## -# Parameter checking -############################################################################## - -# Check all arguments against a very restricted set of allowed characters and -# to ensure the right number of arguments are taken. The arguments are the -# number of arguments expected (minimum and maximum), a reference to an array -# of which argument numbers shouldn't be checked, and then the arguments. -# -# This function is probably temporary and will be replaced with something that -# knows more about the syntax of each command and can check more things. -sub check_args { - my ($min, $max, $exclude, @args) = @_; - if (@args < $min) { - error "insufficient arguments"; - } elsif (@args > $max and $max != -1) { - error "too many arguments"; - } - my %exclude = map { $_ => 1 } @$exclude; - for (my $i = 1; $i <= @args; $i++) { - next if $exclude{$i}; - unless ($args[$i - 1] =~ m,^[\w_/\@.-]*\z,) { - error "invalid characters in argument: $args[$i - 1]"; - } - } -} - -############################################################################## -# Implementation -############################################################################## - -# Parse and execute a command. We wrap this in a subroutine call for easier -# testing. -sub command { - log_init; - my $user = $ENV{REMOTE_USER} or error "REMOTE_USER not set"; - my $host = $ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR} - or error "neither REMOTE_HOST nor REMOTE_ADDR set"; - - # Instantiate the server object. - my $server = Wallet::Server->new ($user, $host); - - # Parse command-line options and dispatch to the appropriate calls. - my ($command, @args) = @_; - if ($command eq 'acl') { - my $action = shift @args; - if ($action eq 'add') { - check_args (3, 3, [3], @args); - $server->acl_add (@args) or failure ($server->error, @_); - } elsif ($action eq 'check') { - check_args (1, 1, [], @args); - my $status = $server->acl_check (@args); - if (!defined ($status)) { - failure ($server->error, @_); - } else { - print $status ? "yes\n" : "no\n"; - } - } elsif ($action eq 'create') { - check_args (1, 1, [], @args); - $server->acl_create (@args) or failure ($server->error, @_); - } elsif ($action eq 'destroy') { - check_args (1, 1, [], @args); - $server->acl_destroy (@args) or failure ($server->error, @_); - } elsif ($action eq 'history') { - check_args (1, 1, [], @args); - my $output = $server->acl_history (@args); - if (defined $output) { - print $output; - } else { - failure ($server->error, @_); - } - } elsif ($action eq 'remove') { - check_args (3, 3, [3], @args); - $server->acl_remove (@args) or failure ($server->error, @_); - } elsif ($action eq 'rename') { - check_args (2, 2, [], @args); - $server->acl_rename (@args) or failure ($server->error, @_); - } elsif ($action eq 'replace') { - check_args (2, 2, [], @args); - $server->acl_replace (@args) or failure ($server->error, @_); - } elsif ($action eq 'show') { - check_args (1, 1, [], @args); - my $output = $server->acl_show (@args); - if (defined $output) { - print $output; - } else { - failure ($server->error, @_); - } - } else { - error "unknown command acl $action"; - } - } elsif ($command eq 'autocreate') { - check_args (2, 2, [], @args); - $server->autocreate (@args) or failure ($server->error, @_); - } elsif ($command eq 'check') { - check_args (2, 2, [], @args); - my $status = $server->check (@args); - if (!defined ($status)) { - failure ($server->error, @_); - } else { - print $status ? "yes\n" : "no\n"; - } - } elsif ($command eq 'comment') { - check_args (2, 3, [3], @args); - if (@args > 2) { - $server->comment (@args) or failure ($server->error, @_); - } else { - my $output = $server->comment (@args); - if (defined $output) { - print $output, "\n"; - } elsif (not $server->error) { - print "No comment set\n"; - } else { - failure ($server->error, @_); - } - } - } elsif ($command eq 'create') { - check_args (2, 2, [], @args); - $server->create (@args) or failure ($server->error, @_); - } elsif ($command eq 'destroy') { - check_args (2, 2, [], @args); - $server->destroy (@args) or failure ($server->error, @_); - } elsif ($command eq 'expires') { - check_args (2, 3, [], @args); - if (@args > 2) { - $server->expires (@args) or failure ($server->error, @_); - } else { - my $output = $server->expires (@args); - if (defined $output) { - print $output, "\n"; - } elsif (not $server->error) { - print "No expiration set\n"; - } else { - failure ($server->error, @_); - } - } - } elsif ($command eq 'flag') { - my $action = shift @args; - check_args (3, 3, [], @args); - if ($action eq 'clear') { - $server->flag_clear (@args) or failure ($server->error, @_); - } elsif ($action eq 'set') { - $server->flag_set (@args) or failure ($server->error, @_); - } else { - error "unknown command flag $action"; - } - } elsif ($command eq 'get') { - check_args (2, 2, [], @args); - my $output = $server->get (@args); - if (defined $output) { - print $output; - } else { - failure ($server->error, @_); - } - } elsif ($command eq 'getacl') { - check_args (3, 3, [], @args); - my $output = $server->acl (@args); - if (defined $output) { - print $output, "\n"; - } elsif (not $server->error) { - print "No ACL set\n"; - } else { - failure ($server->error, @_); - } - } elsif ($command eq 'getattr') { - check_args (3, 3, [], @args); - my @result = $server->attr (@args); - if (not @result and $server->error) { - failure ($server->error, @_); - } elsif (@result) { - print join ("\n", @result, ''); - } - } elsif ($command eq 'history') { - check_args (2, 2, [], @args); - my $output = $server->history (@args); - if (defined $output) { - print $output; - } else { - failure ($server->error, @_); - } - } elsif ($command eq 'owner') { - check_args (2, 3, [], @args); - if (@args > 2) { - $server->owner (@args) or failure ($server->error, @_); - } else { - my $output = $server->owner (@args); - if (defined $output) { - print $output, "\n"; - } elsif (not $server->error) { - print "No owner set\n"; - } else { - failure ($server->error, @_); - } - } - } elsif ($command eq 'rename') { - check_args (3, 3, [], @args); - $server->rename (@args) or failure ($server->error, @_); - } elsif ($command eq 'setacl') { - check_args (4, 4, [], @args); - $server->acl (@args) or failure ($server->error, @_); - } elsif ($command eq 'setattr') { - check_args (4, -1, [], @args); - $server->attr (@args) or failure ($server->error, @_); - } elsif ($command eq 'show') { - check_args (2, 2, [], @args); - my $output = $server->show (@args); - if (defined $output) { - print $output; - } else { - failure ($server->error, @_); - } - } elsif ($command eq 'store') { - check_args (2, 3, [3], @args); - if (@args == 2) { - local $/; - $args[2] = ; - } - splice (@_, 3); - $server->store (@args) or failure ($server->error, @_); - } elsif ($command eq 'update') { - check_args (2, 2, [], @args); - my $output = $server->update (@args); - if (defined $output) { - print $output; - } else { - failure ($server->error, @_); - } - } else { - error "unknown command $command"; - } - success (@_); -} - -# Parse command-line options. -my ($quiet); -Getopt::Long::config ('require_order'); -GetOptions ('q|quiet' => \$quiet) or exit 1; -$SYSLOG = 0 if $quiet; - -# Run the command. -command (@ARGV); - -__END__ - -############################################################################## -# Documentation -############################################################################## - -# The commands section of this document is duplicated from the documentation -# for wallet and should be kept in sync. - -=for stopwords -wallet-backend backend backend-specific remctld ACL acl timestamp getacl -setacl metadata keytab keytabs enctypes enctype ktadd KDC Allbery -autocreate MERCHANTABILITY NONINFRINGEMENT sublicense - -=head1 NAME - -wallet-backend - Wallet server for storing and retrieving secure data - -=head1 SYNOPSIS - -B [B<-q>] I [I ...] - -=head1 DESCRIPTION - -B implements the interface between B and the -wallet system. It is written to run under B and expects the -authenticated identity of the remote user in the REMOTE_USER environment -variable. It uses REMOTE_HOST or REMOTE_ADDR if REMOTE_HOST isn't set for -additional trace information. It accepts the command from B on -the command line, creates a Wallet::Server object, and calls the -appropriate methods. - -This program is a fairly thin wrapper around Wallet::Server that -translates command strings into method calls and returns the results. It -does check all arguments except for the argument to the store -command and rejects any argument not matching C<^[\w_/.-]+\z>; in other -words, only alphanumerics, underscore (C<_>), slash (C), period (C<.>), -and hyphen (C<->) are permitted in arguments. This provides some -additional security over and above the checking already done by the rest -of the wallet code. - -=head1 OPTIONS - -=over 4 - -=item B<--quiet>, B<-q> - -If this option is given, B will not log its actions to -syslog. - -=back - -=head1 COMMANDS - -Most commands are only available to wallet administrators (users on the -C ACL). The exceptions are C, C, C, -C, C, C, C, C, C, -C, and C. C and C can be run by -anyone. All of the rest of those commands have their own ACLs except -C and C, which use the C ACL, C, which -uses the C ACL, and C, which uses the owner or C ACL -depending on whether one is setting or retrieving the comment. If the -appropriate ACL is set, it alone is checked to see if the user has access. -Otherwise, C, C, C, C, C, C, -C, and C access is permitted if the user is authorized -by the owner ACL of the object. - -Administrators can run any command on any object or ACL except for C -and C. For C and C, they must still be authorized by -either the appropriate specific ACL or the owner ACL. - -If the locked flag is set on an object, no commands can be run on that -object that change data except the C commands, nor can the C -command be used on that object. C, C, C, -C, and C, C, or C without an argument -can still be used on that object. - -For more information on attributes, see L. - -=over 4 - -=item acl add - -Add an entry with and to the ACL . may be -either the name of an ACL or its numeric identifier. - -=item acl check - -Check whether an ACL with the ID already exists. If it does, prints -C; if not, prints C. - -=item acl create - -Create a new, empty ACL with name . When setting an ACL on an -object with a set of entries that don't match an existing ACL, first -create a new ACL with C, add the appropriate entries to it -with C, and then set the ACL on an object with the C or -C commands. - -=item acl destroy - -Destroy the ACL . This ACL must no longer be referenced by any object -or the ACL destruction will fail. The special ACL named C cannot -be destroyed. - -=item acl history - -Display the history of the ACL . Each change to the ACL (not -including changes to the name of the ACL) will be represented by two -lines. The first line will have a timestamp of the change followed by a -description of the change, and the second line will give the user who made -the change and the host from which the change was made. - -=item acl remove - -Remove the entry with and from the ACL . -may be either the name of an ACL or its numeric identifier. The last -entry in the special ACL C cannot be removed to protect against -accidental lockout, but administrators can remove themselves from the -C ACL and can leave only a non-functioning entry on the ACL. Use -caution when removing entries from the C ACL. - -=item acl rename - -Renames the ACL identified by to . This changes the -human-readable name, not the underlying numeric ID, so the ACL's -associations with objects will be unchanged. The C ACL may not be -renamed. may be either the current name or the numeric ID. -must not be all-numeric. To rename an ACL, the current user must be -authorized by the C ACL. - -=item acl replace - -Find any objects owned by , and then change their ownership to - instead. should already exist, and may already have -some objects owned by it. is not deleted afterwards, though in -most cases that is probably your next step. The C ACL may not be -replaced from. and may be either the current name or the -numeric ID. To replace an ACL, the current user must be authorized by -the C ACL. - -=item acl show - -Display the name, numeric ID, and entries of the ACL . - -=item autocreate - -Create a new object of type with name . The user must be -listed in the default ACL for an object with that type and name, and the -object will be created with that default ACL set as the object owner. - -=item check - -Check whether an object of type and name already exists. If -it does, prints C; if not, prints C. - -=item comment [] - -If is not given, displays the current comment for the object -identified by and , or C if none is set. - -If is given, sets the comment on the object identified by - and to . If is the empty string, clears -the comment. - -=item create - -Create a new object of type with name . With some backends, -this will trigger creation of an entry in an external system as well. -The new object will have no ACLs and no owner set, so usually the -administrator will want to then set an owner with C so that the -object will be usable. - -=item destroy - -Destroy the object identified by and . With some backends, -this will trigger destruction of an object in an external system as well. - -=item expires [ [