diff options
author | Russ Allbery <rra@stanford.edu> | 2007-09-19 22:43:15 +0000 |
---|---|---|
committer | Russ Allbery <rra@stanford.edu> | 2007-09-19 22:43:15 +0000 |
commit | 9d5ee8d947433edd542ed441136d19e4f4033af4 (patch) | |
tree | d8cab026fbeca63f1c28b9c41d449cd8348b294b /perl/Wallet | |
parent | e86a7a0569e84ebcb769855ece2417c2ccce9b45 (diff) |
Implement unchanging support in the keytab object backend, which retrieves
keytabs via remctl from the KDC.
Diffstat (limited to 'perl/Wallet')
-rw-r--r-- | perl/Wallet/Config.pm | 44 | ||||
-rw-r--r-- | perl/Wallet/Object/Keytab.pm | 52 |
2 files changed, 95 insertions, 1 deletions
diff --git a/perl/Wallet/Config.pm b/perl/Wallet/Config.pm index 4bc8e2f..9a1f9db 100644 --- a/perl/Wallet/Config.pm +++ b/perl/Wallet/Config.pm @@ -170,6 +170,17 @@ client. =over 4 +=item KEYTAB_CACHE + +Specifies the ticket cache to use when retrieving existing keytabs from the +KDC. This is only used to implement support for the C<unchanging> flag. +The ticket cache must be for a principal with access to run C<keytab +retrieve> via remctl on KEYTAB_REMCTL_HOST. + +=cut + +our $KEYTAB_CACHE; + =item KEYTAB_FILE Specifies the keytab to use to authenticate to B<kadmind>. The principal @@ -245,6 +256,39 @@ default to the local realm. our $KEYTAB_REALM; +=item KEYTAB_REMCTL_HOST + +The host to which to connect with remctl to retrieve existing keytabs. This +is only used to implement support for the C<unchanging> flag. This host +must provide the C<keytab retrieve> command and KEYTAB_CACHE must also be +set to a ticket cache for a principal with access to run that command. + +=cut + +our $KEYTAB_REMCTL_HOST; + +=item KEYTAB_REMCTL_PRINCIPAL + +The service principal to which to authenticate when retrieving existing +keytabs. This is only used to implement support for the C<unchanging> flag. +If this variable is not set, the default is formed by prepending C<host/> to +KEYTAB_REMCTL_HOST. (Note that KEYTAB_REMCTL_HOST is not lowercased first.) + +=cut + +our $KEYTAB_REMCTL_PRINCIPAL; + +=item KEYTAB_REMCTL_PORT + +The port on KEYTAB_REMCTL_HOST to which to connect with remctl to retrieve +existing keytabs. This is only used to implement support for the +C<unchanging> flag. If this variable is not set, the default remctl port +will be used. + +=cut + +our $KEYTAB_REMCTL_PORT; + =item KEYTAB_TMP A directory into which the wallet can write keytabs temporarily while diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index 41a679e..582f78c 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -172,7 +172,50 @@ sub kadmin_delprinc { } ############################################################################## -# Implementation +# Keytab retrieval +############################################################################## + +# Retrieve an existing keytab from the KDC via a remctl call. The KDC needs +# to be running the keytab-backend script and support the keytab retrieve +# remctl command. In addition, the user must have configured us with the path +# to a ticket cache and the host to which to connect with remctl. Returns the +# keytab on success and undef on failure. +sub keytab_retrieve { + my ($self, $keytab) = @_; + my $host = $Wallet::Config::KEYTAB_REMCTL_HOST; + unless ($host and $Wallet::Config::KEYTAB_CACHE) { + $self->error ('keytab unchanging support not configured'); + return undef; + } + eval { require Net::Remctl }; + if ($@) { + $self->error ("keytab unchanging support not available: $@"); + return undef; + } + if ($Wallet::Config::KEYTAB_REALM) { + $keytab .= '@' . $Wallet::Config::KEYTAB_REALM; + } + local $ENV{KRB5CCNAME} = $Wallet::Config::KEYTAB_CACHE; + my $port = $Wallet::Config::KEYTAB_REMCTL_PORT; + my $principal = $Wallet::Config::KEYTAB_REMCTL_PRINCIPAL; + my @command = ('keytab', 'retrieve', $keytab); + my $result = Net::Remctl::remctl ($host, $port, $principal, @command); + if ($result->error) { + $self->error ("cannot retrieve keytab for $keytab: ", $result->error); + return undef; + } elsif ($result->status != 0) { + my $error = $result->stderr; + $error =~ s/\s+$//; + $error =~ s/\n/ /g; + $self->error ("cannot retrieve keytab for $keytab: $error"); + return undef; + } else { + return $result->stdout; + } +} + +############################################################################## +# Core methods ############################################################################## # Override create to start by creating the principal in Kerberos and only @@ -207,6 +250,13 @@ sub get { $self->error ("cannot get $id: object is locked"); return; } + if ($self->flag_check ('unchanging')) { + my $result = $self->keytab_retrieve ($self->{name}); + if (defined $result) { + $self->log_action ('get', $user, $host, $time); + } + return $result; + } unless (defined ($Wallet::Config::KEYTAB_TMP)) { $self->error ('KEYTAB_TMP configuration variable not set'); return undef; |