summaryrefslogtreecommitdiff
path: root/perl/lib/Wallet/Kadmin.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl/lib/Wallet/Kadmin.pm')
-rw-r--r--perl/lib/Wallet/Kadmin.pm241
1 files changed, 241 insertions, 0 deletions
diff --git a/perl/lib/Wallet/Kadmin.pm b/perl/lib/Wallet/Kadmin.pm
new file mode 100644
index 0000000..65a5700
--- /dev/null
+++ b/perl/lib/Wallet/Kadmin.pm
@@ -0,0 +1,241 @@
+# Wallet::Kadmin -- Kerberos administration API for wallet keytab backend.
+#
+# Written by Jon Robertson <jonrober@stanford.edu>
+# Copyright 2009, 2010, 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# See LICENSE for licensing terms.
+
+##############################################################################
+# Modules and declarations
+##############################################################################
+
+package Wallet::Kadmin;
+require 5.006;
+
+use strict;
+use warnings;
+use vars qw($VERSION);
+
+use Wallet::Config ();
+
+# This version should be increased on any code change to this module. Always
+# use two digits for the minor version with a leading zero if necessary so
+# that it will sort properly.
+$VERSION = '0.03';
+
+##############################################################################
+# Utility functions for child classes
+##############################################################################
+
+# Read the entirety of a possibly binary file and return the contents,
+# deleting the file after reading it. If reading the file fails, set the
+# error message and return undef.
+sub read_keytab {
+ my ($self, $file) = @_;
+ local *TMPFILE;
+ unless (open (TMPFILE, '<', $file)) {
+ $self->error ("cannot open temporary file $file: $!");
+ return;
+ }
+ local $/;
+ undef $!;
+ my $data = <TMPFILE>;
+ if ($!) {
+ $self->error ("cannot read temporary file $file: $!");
+ unlink $file;
+ return;
+ }
+ close TMPFILE;
+ unlink $file;
+ return $data;
+}
+
+##############################################################################
+# Public methods
+##############################################################################
+
+# Create a new kadmin object, by finding the type requested in the wallet
+# config and passing off to the proper module. Returns the object directly
+# from the specific Wallet::Kadmin::* module.
+sub new {
+ my ($class) = @_;
+ my $kadmin;
+ if (not $Wallet::Config::KEYTAB_KRBTYPE) {
+ die "keytab object implementation not configured\n";
+ } elsif (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'mit') {
+ require Wallet::Kadmin::MIT;
+ $kadmin = Wallet::Kadmin::MIT->new;
+ } elsif (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'heimdal') {
+ require Wallet::Kadmin::Heimdal;
+ $kadmin = Wallet::Kadmin::Heimdal->new;
+ } else {
+ my $type = $Wallet::Config::KEYTAB_KRBTYPE;
+ die "unknown KEYTAB_KRBTYPE setting: $type\n";
+ }
+
+ return $kadmin;
+}
+
+# Set or return the error stashed in the object.
+sub error {
+ my ($self, @error) = @_;
+ if (@error) {
+ my $error = join ('', @error);
+ chomp $error;
+ 1 while ($error =~ s/ at \S+ line \d+\.?\z//);
+ $self->{error} = $error;
+ }
+ return $self->{error};
+}
+
+# Set a callback to be called for forked kadmin processes. This does nothing
+# by default but may be overridden by subclasses that need special behavior
+# (such as the current Wallet::Kadmin::MIT module).
+sub fork_callback { }
+
+1;
+__END__
+
+##############################################################################
+# Documentation
+##############################################################################
+
+=for stopwords
+backend Kadmin keytabs keytab Heimdal API kadmind kadmin KDC ENCTYPE
+enctypes enctype Allbery
+
+=head1 NAME
+
+Wallet::Kadmin - Kerberos administration API for wallet keytab backend
+
+=head1 SYNOPSIS
+
+ my $kadmin = Wallet::Kadmin->new;
+ $kadmin->create ('host/foo.example.com');
+ my $data = $kadmin->keytab_rekey ('host/foo.example.com',
+ 'aes256-cts-hmac-sha1-96');
+ $data = $kadmin->keytab ('host/foo.example.com');
+ my $exists = $kadmin->exists ('host/oldshell.example.com');
+ $kadmin->destroy ('host/oldshell.example.com') if $exists;
+
+=head1 DESCRIPTION
+
+Wallet::Kadmin is a wrapper and base class for modules that provide an
+interface for wallet to do Kerberos administration, specifically create
+and delete principals and create keytabs for a principal. Each subclass
+administers a specific type of Kerberos implementation, such as MIT
+Kerberos or Heimdal, providing a standard set of API calls used to
+interact with that implementation's kadmin interface.
+
+The class uses Wallet::Config to find which type of kadmin interface is in
+use and then returns an object to use for interacting with that interface.
+See L<Wallet::Config/"KEYTAB OBJECT CONFIGURATION"> for details on how to
+configure this module.
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item new()
+
+Finds the proper Kerberos implementation and calls the new() constructor
+for that implementation's module, returning the resulting object. If the
+implementation is not recognized or set, die with an error message.
+
+=back
+
+=head1 INSTANCE METHODS
+
+These methods are provided by any object returned by new(), regardless of
+the underlying kadmin interface. They are implemented by the child class
+appropriate for the configured Kerberos implementation.
+
+=over 4
+
+=item create(PRINCIPAL)
+
+Adds a new principal with a given name. The principal is created with a
+random password, and any other flags set by Wallet::Config. Returns true
+on success and false on failure. If the principal already exists, return
+true as we are bringing our expectations in line with reality.
+
+=item destroy(PRINCIPAL)
+
+Removes a principal with the given name. Returns true on success or false
+on failure. If the principal does not exist, return true as we are
+bringing our expectations in line with reality.
+
+=item error([ERROR ...])
+
+Returns the error of the last failing operation or undef if no operations
+have failed. Callers should call this function to get the error message
+after an undef return from any other instance method.
+
+For the convenience of child classes, this method can also be called with
+one or more error strings. If so, those strings are concatenated
+together, trailing newlines are removed, any text of the form S<C< at \S+
+line \d+\.?>> at the end of the message is stripped off, and the result is
+stored as the error. Only child classes should call this method with an
+error string.
+
+=item exists(PRINCIPAL)
+
+Returns true if the given principal exists in the KDC and C<0> if it
+doesn't. If an error is encountered in checking whether the principal
+exists, exists() returns undef.
+
+=item fork_callback(CALLBACK)
+
+If the module has to fork an external process for some reason, such as a
+kadmin command-line client, the sub CALLBACK will be called in the child
+process before running the program. This can be used to, for example,
+properly clean up shared database handles.
+
+=item keytab(PRINCIPAL)
+
+keytab() creates a keytab for the given principal, storing it in the given
+file. A keytab is an on-disk store for the key or keys for a Kerberos
+principal. Keytabs are used by services to verify incoming authentication
+from clients or by automated processes that need to authenticate to
+Kerberos. To create a keytab, the principal has to have previously been
+created in the Kerberos KDC. Returns the keytab as binary data on success
+and undef on failure.
+
+=item keytab_rekey(PRINCIPAL [, ENCTYPE ...])
+
+Like keytab(), but randomizes the key for the principal before generating
+the keytab and writes it to the given file. This will invalidate any
+existing keytabs for that principal. This method can also limit the
+encryption types of the keys for that principal via the optional ENCTYPE
+arguments. The enctype values must be enctype strings recognized by the
+Kerberos implementation (strings like C<aes256-cts-hmac-sha1-96> or
+C<des-cbc-crc>). If none are given, the KDC defaults will be used.
+Returns the keytab as binary data on success and undef on failure.
+
+=back
+
+The following methods are utility methods to aid with child class
+implementation and should only be called by child classes.
+
+=over 4
+
+=item read_keytab(FILE)
+
+Reads the contents of the keytab stored in FILE into memory and returns it
+as binary data. On failure, returns undef and sets the object error.
+
+=back
+
+=head1 SEE ALSO
+
+kadmin(8), Wallet::Config(3), Wallet::Object::Keytab(3), wallet-backend(8)
+
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
+
+=head1 AUTHORS
+
+Jon Robertson <jonrober@stanford.edu> and Russ Allbery <eagle@eyrie.org>
+
+=cut