From 0e6b6e3be0d1c544871445a580de7da502fec8c0 Mon Sep 17 00:00:00 2001 From: Jon Robertson Date: Thu, 10 Dec 2009 14:40:59 -0800 Subject: Added support for Heimdal KDC Added support for Heimdal as an alternative to MIT Kerberos. This involved separating out the kadmin-specific code into its own set of modules, and changing the existing Wallet::Object::Keytab code to branch based on which module is loaded. --- perl/Wallet/Kadmin.pm | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 perl/Wallet/Kadmin.pm (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm new file mode 100644 index 0000000..b804861 --- /dev/null +++ b/perl/Wallet/Kadmin.pm @@ -0,0 +1,110 @@ +# Wallet::Kadmin -- Kadmin module wrapper for the wallet. +# +# Written by Jon Robertson +# Copyright 2009 Board of Trustees, Leland Stanford Jr. University +# +# See LICENSE for licensing terms. + +############################################################################## +# Modules and declarations +############################################################################## + +package Wallet::Kadmin; +require 5.006; + +use strict; +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.01'; + +############################################################################## +# Constructor +############################################################################## + +# 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 ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { + require Wallet::Kadmin::MIT; + $kadmin = Wallet::Kadmin::MIT->new (); + } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { + require Wallet::Kadmin::Heimdal; + $kadmin = Wallet::Kadmin::Heimdal->new (); + } else { + die "keytab krb server type not set to a valid value\n"; + } + + return $kadmin; +} + +1; +__END__ + +############################################################################## +# Documentation +############################################################################## + +=head1 NAME + +Wallet::Kadmin - Kadmin module wrapper for wallet keytabs + +=head1 SYNOPSIS + + my $kadmin = Wallet::Kadmin->new (); + $kadmin->addprinc ("host/shell.example.com"); + $kadmin->ktadd ("host/shell.example.com", "aes256-cts"); + my $exists = $kadmin->exists ("host/oldshell.example.com"); + $kadmin->delprinc ("host/oldshell.example.com") if $exists; + +=head1 DESCRIPTION + +Wallet::Kadmin is a wrapper to modules that provide an interface for keytab +integration with the wallet. Each module is meant to interface with a +specific type of Kerberos implementation, such as MIT Kerberos or Heimdal +Kerberos, and provide a standndard set of API calls used to interact with +that implementation's kadmind. + +The class simply uses Wallet::Config to find which type of kadmind we have +requested to use, and then returns an object to use for interacting with +that kadmind. + +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 be created in Kerberos and then a keytab is +generated and stored in a file on disk. + +To use this object, several configuration parameters must be set. See +Wallet::Config(3) for details on those configuration parameters and +information about how to set wallet configuration. + +=head1 METHODS + +=over 4 + +=item new() + +Finds the proper Kerberos implementation and calls the new() constructor for +that implementation's module, returning the result. If the implementation +is not recognized or set, die with an error message. + +=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. + +=head1 AUTHORS + +Jon Robertson + +=cut -- cgit v1.2.3 From 236e209c3fefa0a56784ec3cd810a0bb5383b86d Mon Sep 17 00:00:00 2001 From: Jon Robertson Date: Wed, 16 Dec 2009 20:32:37 -0800 Subject: Provided path to call valid_principal directly valid_principal used to reside in Wallet::Object::Keytab, but was moved to the individual Wallet::Kadmin::* modules. This isn't necessary currently and may not ever be, but it's there just in case we do ever need to differentiate. To simplify testing, a way to still call it directly from Wallet::Object::Keytab has been added. --- perl/Wallet/Kadmin.pm | 28 ++++++++++++++++++++++++++-- perl/Wallet/Object/Keytab.pm | 14 +++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index b804861..33c84a1 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -20,12 +20,27 @@ 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.01'; +$VERSION = '0.02'; ############################################################################## -# Constructor +# Public methods ############################################################################## +# Validate a principal with a submodule's validator. We can also do this via +# creating an object with new and then running valid_principal from that, +# but there are times we might wish to run it without going through the +# object creation. +sub valid_principal { + my ($class, $principal) = @_; + if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { + require Wallet::Kadmin::MIT; + return Wallet::Kadmin::MIT->valid_principal ($principal); + } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { + require Wallet::Kadmin::Heimdal; + return Wallet::Kadmin::Heimdal->valid_principal ($principal); + } +} + # 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. @@ -96,6 +111,15 @@ Finds the proper Kerberos implementation and calls the new() constructor for that implementation's module, returning the result. If the implementation is not recognized or set, die with an error message. +=item valid_principal(PRINCIPAL) + +Finds the proper Kerberos implementation and calls its own valid_principal +method, returning the result. This tells whether a principal is valid for +that implementation. This can be achieved by using new() and then directly +calling valid_principal on the returned object -- this method is a shortcut +in case we want to check validity without creating the object and worrying +about proper setup. + =head1 SEE ALSO kadmin(8), Wallet::Config(3), Wallet::Object::Keytab(3), wallet-backend(8) diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index 1732070..b1c9d6d 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -491,6 +491,13 @@ sub create { return $self; } +# Provides wrapper to individual Kadmin class's valid_principal. Here only +# to help expose for testing. +sub valid_principal { + my ($self, $principal) = @_; + return Wallet::Kadmin->valid_principal ($principal); +} + # Override destroy to delete the principal out of Kerberos as well. sub destroy { my ($self, $user, $host, $time) = @_; @@ -547,7 +554,12 @@ sub get { unlink $file; my @enctypes = $self->attr ('enctypes'); my $kadmin = $self->{kadmin}; - return if not $kadmin->ktadd ($self->{name}, $file, @enctypes); + my $retval = eval { $kadmin->ktadd ($self->{name}, $file, @enctypes) }; + if ($@) { + $self->error ($@); + return; + } + return unless $retval; local *KEYTAB; unless (open (KEYTAB, '<', $file)) { my $princ = $self->{name}; -- cgit v1.2.3 From d684049761db4eb88cd936c530196ea89a524c07 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Tue, 19 Jan 2010 22:48:01 -0800 Subject: Coding style fixes for Perl wallet code Strip trailing whitespace, convert tabs to spaces, add newlines to exceptions, and remove a few stray blank lines and a few other minor coding style oddities. Make the SQL style consistent. --- perl/Wallet/Admin.pm | 105 +++++++++++++++---------------- perl/Wallet/Kadmin.pm | 10 +-- perl/Wallet/Kadmin/Heimdal.pm | 102 ++++++++++++++---------------- perl/Wallet/Kadmin/MIT.pm | 32 +++++----- perl/Wallet/Object/Base.pm | 12 ++-- perl/Wallet/Object/Keytab.pm | 13 ++-- perl/t/admin.t | 4 +- perl/t/keytab.t | 140 ++++++++++++++++++++---------------------- 8 files changed, 198 insertions(+), 220 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Admin.pm b/perl/Wallet/Admin.pm index 0e437ec..701c813 100644 --- a/perl/Wallet/Admin.pm +++ b/perl/Wallet/Admin.pm @@ -114,23 +114,22 @@ sub destroy { # Reporting ############################################################################## -# Given an ACL name, translate it to the ID for that ACL and return it. +# Given an ACL name, translate it to the ID for that ACL and return it. # Often this is unneeded and could be done with a join, but by doing it in a -# separate step, we can give an error for the specific case of someone +# separate step, we can give an error for the specific case of someone # searching for a non-existant ACL. sub acl_name_to_id { my ($self, $acl) = @_; my ($id); eval { - my $sql = 'select ac_id from acls where ac_name=?'; - my $sth = $self->{dbh}->prepare ($sql); - $sth->execute ($acl); - while (defined (my $row = $sth->fetchrow_hashref)) { - $id = $row->{'ac_id'}; - } - $self->{dbh}->commit; + my $sql = 'select ac_id from acls where ac_name = ?'; + my $sth = $self->{dbh}->prepare ($sql); + $sth->execute ($acl); + while (defined (my $row = $sth->fetchrow_hashref)) { + $id = $row->{ac_id}; + } + $self->{dbh}->commit; }; - if (!defined $id || $id !~ /^\d+$/) { $self->error ("could not find the acl $acl"); return ''; @@ -155,7 +154,7 @@ sub list_objects_type { return ($sql, $type); } -# Return the SQL statement and search field required to find all objects +# Return the SQL statement and search field required to find all objects # owned by a given ACL. If the requested owner is 'null', then we ignore # this and do a different search for IS NULL. If the requested owner does # not actually match any ACLs, set an error and return the empty string. @@ -163,15 +162,15 @@ sub list_objects_owner { my ($self, $owner) = @_; my ($sth); if ($owner =~ /^null$/i) { - my $sql = 'select ob_type, ob_name from objects where ob_owner is null + my $sql = 'select ob_type, ob_name from objects where ob_owner is null order by objects.ob_type, objects.ob_name'; - return ($sql); + return ($sql); } else { - my $id = $self->acl_name_to_id ($owner); - return '' unless $id; - my $sql = 'select ob_type, ob_name from objects where ob_owner=? + my $id = $self->acl_name_to_id ($owner); + return '' unless $id; + my $sql = 'select ob_type, ob_name from objects where ob_owner = ? order by objects.ob_type, objects.ob_name'; - return ($sql, $id); + return ($sql, $id); } } @@ -180,26 +179,24 @@ sub list_objects_owner { sub list_objects_flag { my ($self, $flag) = @_; my $sql = 'select ob_type, ob_name from objects left join flags on - (objects.ob_type=flags.fl_type AND objects.ob_name=flags.fl_name) - where flags.fl_flag=? order by objects.ob_type, objects.ob_name'; + (objects.ob_type = flags.fl_type and objects.ob_name = flags.fl_name) + where flags.fl_flag = ? order by objects.ob_type, objects.ob_name'; return ($sql, $flag); } -# Return the SQL statement and search field required to find all objects +# Return the SQL statement and search field required to find all objects # that a given ACL has any permissions on. This expands from # list_objects_owner in that it will also match any records that have the ACL # set for get, store, show, destroy, or flags. If the requested owner does # not actually match any ACLs, set an error and return the empty string. sub list_objects_acl { my ($self, $acl) = @_; - my $id = $self->acl_name_to_id ($acl); return '' unless $id; - - my $sql = 'select ob_type, ob_name from objects where - ob_owner=? or ob_acl_get=? or ob_acl_store=? or ob_acl_show=? or - ob_acl_destroy=? or ob_acl_flags=? - order by objects.ob_type, objects.ob_name'; + my $sql = 'select ob_type, ob_name from objects where ob_owner = ? or + ob_acl_get = ? or ob_acl_store = ? or ob_acl_show = ? or + ob_acl_destroy = ? or ob_acl_flags = ? order by objects.ob_type, + objects.ob_name'; return ($sql, $id, $id, $id, $id, $id, $id); } @@ -217,29 +214,29 @@ sub list_objects { my $sql = ''; my @search = (); if (!defined $type || $type eq '') { - ($sql) = $self->list_objects_all (); + ($sql) = $self->list_objects_all (); } else { - if (@args != 1) { - $self->error ("object searches require an argument to search"); - } elsif ($type eq 'type') { - ($sql, @search) = $self->list_objects_type (@args); - } elsif ($type eq 'owner') { - ($sql, @search) = $self->list_objects_owner (@args); - } elsif ($type eq 'flag') { - ($sql, @search) = $self->list_objects_flag (@args); - } elsif ($type eq 'acl') { - ($sql, @search) = $self->list_objects_acl (@args); - } else { - $self->error ("do not know search type: $type"); - } - return unless $sql; + if (@args != 1) { + $self->error ("object searches require an argument to search"); + } elsif ($type eq 'type') { + ($sql, @search) = $self->list_objects_type (@args); + } elsif ($type eq 'owner') { + ($sql, @search) = $self->list_objects_owner (@args); + } elsif ($type eq 'flag') { + ($sql, @search) = $self->list_objects_flag (@args); + } elsif ($type eq 'acl') { + ($sql, @search) = $self->list_objects_acl (@args); + } else { + $self->error ("do not know search type: $type"); + } + return unless $sql; } my @objects; eval { my $object; - my $sth = $self->{dbh}->prepare ($sql); - $sth->execute (@search); + my $sth = $self->{dbh}->prepare ($sql); + $sth->execute (@search); while (defined ($object = $sth->fetchrow_arrayref)) { push (@objects, [ @$object ]); } @@ -265,19 +262,19 @@ sub list_acls_all { # the db. sub list_acls_empty { my ($self) = @_; - my $sql = 'select ac_id, ac_name from acls left join acl_entries ' - .'on (acls.ac_id=acl_entries.ae_id) where ae_id is null;'; + my $sql = 'select ac_id, ac_name from acls left join acl_entries + on (acls.ac_id = acl_entries.ae_id) where ae_id is null'; return ($sql); } # Returns the SQL statement and the field required to search the ACLs and -# return only those entries which contain a entries with identifiers +# return only those entries which contain a entries with identifiers # matching a particular given string. sub list_acls_entry { my ($self, $type, $identifier) = @_; - my $sql = 'select distinct ac_id, ac_name from acl_entries - left join acls on (ae_id=ac_id) where ae_scheme=? and - ae_identifier like ? order by ac_id'; + my $sql = 'select distinct ac_id, ac_name from acl_entries left join acls + on (ae_id = ac_id) where ae_scheme = ? and ae_identifier like ? order + by ac_id'; $identifier = '%'.$identifier.'%'; return ($sql, $type, $identifier); } @@ -299,11 +296,11 @@ sub list_acls { ($sql) = $self->list_acls_all (); } else { if ($type eq 'entry') { - if (@args == 0) { - $self->error ("acl searches require an argument to search"); - } else { - ($sql, @search) = $self->list_acls_entry (@args); - } + if (@args == 0) { + $self->error ("acl searches require an argument to search"); + } else { + ($sql, @search) = $self->list_acls_entry (@args); + } } elsif ($type eq 'empty') { ($sql) = $self->list_acls_empty (); } else { diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 33c84a1..200136c 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -27,8 +27,8 @@ $VERSION = '0.02'; ############################################################################## # Validate a principal with a submodule's validator. We can also do this via -# creating an object with new and then running valid_principal from that, -# but there are times we might wish to run it without going through the +# creating an object with new and then running valid_principal from that, +# but there are times we might wish to run it without going through the # object creation. sub valid_principal { my ($class, $principal) = @_; @@ -48,10 +48,10 @@ sub new { my ($class) = @_; my ($kadmin); if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { - require Wallet::Kadmin::MIT; + require Wallet::Kadmin::MIT; $kadmin = Wallet::Kadmin::MIT->new (); } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { - require Wallet::Kadmin::Heimdal; + require Wallet::Kadmin::Heimdal; $kadmin = Wallet::Kadmin::Heimdal->new (); } else { die "keytab krb server type not set to a valid value\n"; @@ -82,7 +82,7 @@ Wallet::Kadmin - Kadmin module wrapper for wallet keytabs =head1 DESCRIPTION Wallet::Kadmin is a wrapper to modules that provide an interface for keytab -integration with the wallet. Each module is meant to interface with a +integration with the wallet. Each module is meant to interface with a specific type of Kerberos implementation, such as MIT Kerberos or Heimdal Kerberos, and provide a standndard set of API calls used to interact with that implementation's kadmind. diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index e4d175b..a8859bf 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -15,8 +15,7 @@ require 5.006; use strict; use vars qw($VERSION); -use Heimdal::Kadm5 qw (KRB5_KDB_DISALLOW_ALL_TIX); - +use Heimdal::Kadm5 qw(KRB5_KDB_DISALLOW_ALL_TIX); use Wallet::Config (); # This version should be increased on any code change to this module. Always @@ -37,7 +36,7 @@ sub valid_principal { return scalar ($principal =~ m,^[\w-]+(/[\w_.-]+)?\z,); } -# Create a Heimdal::Kadm5 client object and return it. It should load +# Create a Heimdal::Kadm5 client object and return it. It should load # configuration from Wallet::Config. sub kadmin_client { unless (defined ($Wallet::Config::KEYTAB_PRINCIPAL) @@ -45,15 +44,13 @@ sub kadmin_client { and defined ($Wallet::Config::KEYTAB_REALM)) { die "keytab object implementation not configured\n"; } - my $server = $Wallet::Config::KEYTAB_HOST || 'localhost'; - my $client = Heimdal::Kadm5::Client->new( - RaiseErrors => 1, - Server => $server, - Principal => $Wallet::Config::KEYTAB_PRINCIPAL, - Realm => $Wallet::Config::KEYTAB_REALM, - Keytab => $Wallet::Config::KEYTAB_FILE, - ); + my @options = (RaiseErrors => 1, + Server => $server, + Principal => $Wallet::Config::KEYTAB_PRINCIPAL, + Realm => $Wallet::Config::KEYTAB_REALM, + Keytab => $Wallet::Config::KEYTAB_FILE); + my $client = Heimdal::Kadm5::Client->new (@options); return $client; } @@ -70,16 +67,8 @@ sub exists { $principal .= '@' . $Wallet::Config::KEYTAB_REALM; } my $kadmin = $self->{client}; - my $princdata = eval { $kadmin->getPrincipal ($principal) }; - - if ($@) { - die $@; - return 0; - } elsif ($princdata) { - return 1; - } else { - return 0; - } + my $princdata = $kadmin->getPrincipal ($principal); + return $princdata ? 1 : 0; } # Create a principal in Kerberos. Since this is only called by create, it @@ -95,7 +84,7 @@ sub addprinc { if ($Wallet::Config::KEYTAB_REALM) { $principal .= '@' . $Wallet::Config::KEYTAB_REALM; } - die "error adding principal $principal: $@" if $@; + die "error adding principal $principal: $@\n" if $@; return 1 if $exists; # The way Heimdal::Kadm5 works, we create a principal object, create the @@ -106,20 +95,19 @@ sub addprinc { my $kadmin = $self->{client}; my $princdata = $kadmin->makePrincipal ($principal); - # Disable the principal before creating, until we've randomized the + # Disable the principal before creating, until we've randomized the # password. my $attrs = $princdata->getAttributes; $attrs |= KRB5_KDB_DISALLOW_ALL_TIX; $princdata->setAttributes ($attrs); my $password = 'inactive'; - my $retval = eval { $kadmin->createPrincipal ($princdata, $password, 0) }; - die "error adding principal $principal: $@" if $@; - $retval = eval { $kadmin->randKeyPrincipal ($principal) }; - die "error adding principal $principal: $@" if $@; - $retval = eval { $kadmin->enablePrincipal ($principal) }; + eval { + $kadmin->createPrincipal ($princdata, $password, 0); + $kadmin->randKeyPrincipal ($principal); + $kadmin->enablePrincipal ($principal); + }; die "error adding principal $principal: $@" if $@; - return 1; } @@ -130,7 +118,7 @@ sub addprinc { sub ktadd { my ($self, $principal, $file, @enctypes) = @_; unless ($self->valid_principal ($principal)) { - die ("invalid principal name: $principal"); + die "invalid principal name: $principal\n"; } if ($Wallet::Config::KEYTAB_REALM) { $principal .= '@' . $Wallet::Config::KEYTAB_REALM; @@ -138,35 +126,35 @@ sub ktadd { # The way Heimdal works, you can only remove enctypes from a principal, # not add them back in. So we need to run randkeyPrincipal first each - # time to restore all possible enctypes and then whittle them back down + # time to restore all possible enctypes and then whittle them back down # to those we have been asked for this time. my $kadmin = $self->{client}; eval { $kadmin->randKeyPrincipal ($principal) }; - die "error creating keytab for $principal: could not reinit enctypes: $@" + die "error creating keytab for $principal: could not reinit enctypes: $@\n" if $@; my $princdata = eval { $kadmin->getPrincipal ($principal) }; if ($@) { - die "error creating keytab for $principal: $@"; + die "error creating keytab for $principal: $@\n"; } elsif (!$princdata) { - die "error creating keytab for $principal: principal does not exist"; + die "error creating keytab for $principal: principal does not exist\n"; } # Now actually remove any non-requested enctypes, if we requested any. if (@enctypes) { - my (%wanted); - my $alltypes = $princdata->getKeytypes (); - foreach (@enctypes) { $wanted{$_} = 1 } - foreach my $key (@{$alltypes}) { - my $keytype = ${$key}[0]; - next if exists $wanted{$keytype}; - eval { $princdata->delKeytypes ($keytype) }; - die "error removing keytype $keytype from the keytab: $@" if $@; - } - eval { $kadmin->modifyPrincipal ($princdata) }; + my (%wanted); + my $alltypes = $princdata->getKeytypes (); + foreach (@enctypes) { $wanted{$_} = 1 } + foreach my $key (@{$alltypes}) { + my $keytype = ${$key}[0]; + next if exists $wanted{$keytype}; + eval { $princdata->delKeytypes ($keytype) }; + die "error removing keytype $keytype from the keytab: $@\n" if $@; + } + eval { $kadmin->modifyPrincipal ($princdata) }; } eval { $kadmin->extractKeytab ($princdata, $file) }; - die "error creating keytab for principal: $@" if $@; + die "error creating keytab for principal: $@\n" if $@; return 1; } @@ -177,7 +165,7 @@ sub ktadd { sub delprinc { my ($self, $principal) = @_; unless ($self->valid_principal ($principal)) { - die ("invalid principal name: $principal"); + die "invalid principal name: $principal\n"; } my $exists = eval { $self->exists ($principal) }; die $@ if $@; @@ -190,7 +178,7 @@ sub delprinc { my $kadmin = $self->{client}; my $retval = eval { $kadmin->deletePrincipal ($principal) }; - die "error deleting $principal: $@" if $@; + die "error deleting $principal: $@\n" if $@; return 1; } @@ -199,12 +187,12 @@ sub delprinc { ############################################################################## # Create a new MIT kadmin object. Very empty for the moment, but later it -# will probably fill out if we go to using a module rather than calling +# will probably fill out if we go to using a module rather than calling # kadmin directly. sub new { my ($class) = @_; my $self = { - client => kadmin_client (), + client => kadmin_client (), }; bless ($self, $class); return $self; @@ -235,7 +223,7 @@ Wallet::Kadmin::MIT is an interface for keytab integration with the wallet, specifically for using kadmin to create, delete, and add enctypes to keytabs. It implments the wallet kadmin API and provides the necessary glue to MIT Kerberos installs for each of these functions, while allowing the wallet -to keep the details of what type of Kerberos installation is being used +to keep the details of what type of Kerberos installation is being used abstracted. A keytab is an on-disk store for the key or keys for a Kerberos principal. @@ -254,15 +242,15 @@ information about how to set wallet configuration. =item addprinc(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 +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, or throws an error if there was a failure in adding the principal. -If the principal already exists, return true as we are bringing our +If the principal already exists, return true as we are bringing our expectations in line with reality. =item addprinc(PRINCIPAL) -Removes a principal with the given name. Returns true on success, or throws +Removes a principal with the given name. Returns true on success, or throws an error if there was a failure in removing the principal. If the principal does not exist, return true as we are bringing our expectations in line with reality. @@ -270,8 +258,8 @@ reality. =item ktadd(PRINCIPAL, FILE, ENCTYPES) Creates a new keytab for the given principal, as the given file, limited to -the enctypes supplied. The enctype values must be enctype strings recognized -by Kerberos (strings like C or C). An error is +the enctypes supplied. The enctype values must be enctype strings recognized +by Kerberos (strings like C or C). An error is thrown on failure or if the creation fails, otherwise true is returned. =back @@ -279,7 +267,7 @@ thrown on failure or if the creation fails, otherwise true is returned. =head1 LIMITATIONS Currently, this implementation calls an external B program rather - than using a native Perl module and therefore requires B be + than using a native Perl module and therefore requires B be installed and parses its output. It may miss some error conditions if the output of B ever changes. diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index b7d4913..7bbb248 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -130,7 +130,7 @@ sub addprinc { sub ktadd { my ($self, $principal, $file, @enctypes) = @_; unless ($self->valid_principal ($principal)) { - die ("invalid principal name: $principal"); + die "invalid principal name: $principal\n"; } if ($Wallet::Config::KEYTAB_REALM) { $principal .= '@' . $Wallet::Config::KEYTAB_REALM; @@ -143,7 +143,7 @@ sub ktadd { my $output = eval { $self->kadmin ("$command $principal") }; die ($@) if ($@); if ($output =~ /^(?:kadmin|ktadd): (.*)/m) { - die ("error creating keytab for $principal: $1"); + die "error creating keytab for $principal: $1\n"; } return 1; } @@ -154,7 +154,7 @@ sub ktadd { sub delprinc { my ($self, $principal) = @_; unless ($self->valid_principal ($principal)) { - die ("invalid principal name: $principal"); + die "invalid principal name: $principal\n"; } my $exists = eval { $self->exists ($principal) }; die $@ if $@; @@ -167,7 +167,7 @@ sub delprinc { my $output = eval { $self->kadmin ("delprinc -force $principal") }; die $@ if $@; if ($output =~ /^delete_principal: (.*)/m) { - die ("error deleting $principal: $1"); + die "error deleting $principal: $1\n"; } return 1; } @@ -177,12 +177,11 @@ sub delprinc { ############################################################################## # Create a new MIT kadmin object. Very empty for the moment, but later it -# will probably fill out if we go to using a module rather than calling +# will probably fill out if we go to using a module rather than calling # kadmin directly. sub new { my ($class) = @_; - my $self = { - }; + my $self = {}; bless ($self, $class); return $self; } @@ -212,7 +211,7 @@ Wallet::Kadmin::MIT is an interface for keytab integration with the wallet, specifically for using kadmin to create, delete, and add enctypes to keytabs. It implments the wallet kadmin API and provides the necessary glue to MIT Kerberos installs for each of these functions, while allowing the wallet -to keep the details of what type of Kerberos installation is being used +to keep the details of what type of Kerberos installation is being used abstracted. A keytab is an on-disk store for the key or keys for a Kerberos principal. @@ -231,15 +230,15 @@ information about how to set wallet configuration. =item addprinc(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 +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, or throws an error if there was a failure in adding the principal. -If the principal already exists, return true as we are bringing our +If the principal already exists, return true as we are bringing our expectations in line with reality. =item addprinc(PRINCIPAL) -Removes a principal with the given name. Returns true on success, or throws +Removes a principal with the given name. Returns true on success, or throws an error if there was a failure in removing the principal. If the principal does not exist, return true as we are bringing our expectations in line with reality. @@ -247,8 +246,8 @@ reality. =item ktadd(PRINCIPAL, FILE, ENCTYPES) Creates a new keytab for the given principal, as the given file, limited to -the enctypes supplied. The enctype values must be enctype strings recognized -by Kerberos (strings like C or C). An error is +the enctypes supplied. The enctype values must be enctype strings recognized +by Kerberos (strings like C or C). An error is thrown on failure or if the creation fails, otherwise true is returned. =back @@ -256,7 +255,7 @@ thrown on failure or if the creation fails, otherwise true is returned. =head1 LIMITATIONS Currently, this implementation calls an external B program rather - than using a native Perl module and therefore requires B be +than using a native Perl module and therefore requires B be installed and parses its output. It may miss some error conditions if the output of B ever changes. @@ -269,7 +268,6 @@ from L. =head1 AUTHORS -Russ Allbery -Jon Robertson +Russ Allbery and Jon Robertson . =cut diff --git a/perl/Wallet/Object/Base.pm b/perl/Wallet/Object/Base.pm index f2568eb..fea0320 100644 --- a/perl/Wallet/Object/Base.pm +++ b/perl/Wallet/Object/Base.pm @@ -445,7 +445,7 @@ sub flag_set { # History ############################################################################## -# Expand a given ACL id to add its name, for readability. Returns the +# Expand a given ACL id to add its name, for readability. Returns the # original id alone if there was a problem finding the name. sub format_acl_id { my ($self, $id) = @_; @@ -455,7 +455,7 @@ sub format_acl_id { my $sth = $self->{dbh}->prepare ($sql); $sth->execute ($id); if (my @ref = $sth->fetchrow_array) { - $name = $ref[0] . " ($id)"; + $name = $ref[0] . " ($id)"; } return $name; @@ -492,11 +492,11 @@ sub history { } elsif (defined ($new)) { $output .= "add $new to attribute $attr"; } - } elsif ($data[0] eq 'set' - and ($data[1] eq 'owner' or $data[1] =~ /^acl_/)) { + } elsif ($data[0] eq 'set' + and ($data[1] eq 'owner' or $data[1] =~ /^acl_/)) { my $field = $data[1]; - $old = $self->format_acl_id ($old) if defined ($old); - $new = $self->format_acl_id ($new) if defined ($new); + $old = $self->format_acl_id ($old) if defined ($old); + $new = $self->format_acl_id ($new) if defined ($new); if (defined ($old) and defined ($new)) { $output .= "set $field to $new (was $old)"; } elsif (defined ($new)) { diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index b1c9d6d..a361599 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -1,7 +1,7 @@ # Wallet::Object::Keytab -- Keytab object implementation for the wallet. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2009 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -477,15 +477,14 @@ sub new { # caller. sub create { my ($class, $type, $name, $dbh, $creator, $host, $time) = @_; - my $self = { - dbh => $dbh, - kadmin => undef, + my $self = { + dbh => $dbh, + kadmin => undef, }; bless $self, $class; my $kadmin = Wallet::Kadmin->new (); $self->{kadmin} = $kadmin; $kadmin->addprinc ($name); - $self = $class->SUPER::create ($type, $name, $dbh, $creator, $host, $time); $self->{kadmin} = $kadmin; return $self; @@ -556,8 +555,8 @@ sub get { my $kadmin = $self->{kadmin}; my $retval = eval { $kadmin->ktadd ($self->{name}, $file, @enctypes) }; if ($@) { - $self->error ($@); - return; + $self->error ($@); + return; } return unless $retval; local *KEYTAB; diff --git a/perl/t/admin.t b/perl/t/admin.t index 77c786d..e963857 100755 --- a/perl/t/admin.t +++ b/perl/t/admin.t @@ -120,7 +120,7 @@ is ($lines[2][1], 'admin@EXAMPLE.COM', ' and the right identifier'); # owned by ADMIN or with any permissions from it. is ($server->create ('base', 'service/null'), 1, 'Creating base:service/null succeeds'); -is ($server->acl ('base', 'service/foo', 'get', 'ADMIN'), 1, +is ($server->acl ('base', 'service/foo', 'get', 'ADMIN'), 1, 'Changing the get ACL for the search also does'); @lines = $admin->list_objects ('owner', 'ADMIN'); is (scalar (@lines), 1, 'Searching for objects owned by ADMIN finds one'); @@ -150,7 +150,7 @@ is ($lines[2][1], 'service/null', ' and the right name'); is (scalar (@lines), 0, 'Searching for all objects of type keytab finds none'); # Test setting a flag, searching for objects with it, and then clearing it. -is ($server->flag_set ('base', 'service/admin', 'unchanging'), 1, +is ($server->flag_set ('base', 'service/admin', 'unchanging'), 1, 'Setting a flag works'); @lines = $admin->list_objects ('flag', 'unchanging'); is (scalar (@lines), 1, 'Searching for all objects with that flag finds one'); diff --git a/perl/t/keytab.t b/perl/t/keytab.t index 5c9ee68..3cd77d8 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -8,7 +8,7 @@ # See LICENSE for licensing terms. use POSIX qw(strftime); -use Test::More tests => 221; +use Test::More tests => 219; use Wallet::Admin; use Wallet::Config; @@ -57,15 +57,15 @@ sub system_quiet { sub create { my ($principal) = @_; if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { - my @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, '-k', - '-t', $Wallet::Config::KEYTAB_FILE, - '-r', $Wallet::Config::KEYTAB_REALM, - '-q', "addprinc -clearpolicy -randkey $principal"); + my @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, '-k', + '-t', $Wallet::Config::KEYTAB_FILE, + '-r', $Wallet::Config::KEYTAB_REALM, + '-q', "addprinc -clearpolicy -randkey $principal"); } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { - @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, - '-K', $Wallet::Config::KEYTAB_FILE, - '-r', $Wallet::Config::KEYTAB_REALM, - 'add', $principal); + @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, + '-K', $Wallet::Config::KEYTAB_FILE, + '-r', $Wallet::Config::KEYTAB_REALM, + 'add', $principal); } system_quiet ($Wallet::Config::KEYTAB_KADMIN, @args); } @@ -76,15 +76,15 @@ sub destroy { my ($principal) = @_; my (@args); if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { - @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, '-k', - '-t', $Wallet::Config::KEYTAB_FILE, - '-r', $Wallet::Config::KEYTAB_REALM, - '-q', "delprinc -force $principal"); + @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, '-k', + '-t', $Wallet::Config::KEYTAB_FILE, + '-r', $Wallet::Config::KEYTAB_REALM, + '-q', "delprinc -force $principal"); } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { - @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, - '-K', $Wallet::Config::KEYTAB_FILE, - '-r', $Wallet::Config::KEYTAB_REALM, - 'delete', $principal); + @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, + '-K', $Wallet::Config::KEYTAB_FILE, + '-r', $Wallet::Config::KEYTAB_REALM, + 'delete', $principal); } system_quiet ($Wallet::Config::KEYTAB_KADMIN, @args); } @@ -95,15 +95,15 @@ sub created { my ($principal) = @_; $principal .= '@' . $Wallet::Config::KEYTAB_REALM; if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { - local $ENV{KRB5CCNAME} = 'krb5cc_temp'; - getcreds ('t/data/test.keytab', $Wallet::Config::KEYTAB_PRINCIPAL); - return (system_quiet ('kvno', $principal) == 0); + local $ENV{KRB5CCNAME} = 'krb5cc_temp'; + getcreds ('t/data/test.keytab', $Wallet::Config::KEYTAB_PRINCIPAL); + return (system_quiet ('kvno', $principal) == 0); } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { - @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, - '-K', $Wallet::Config::KEYTAB_FILE, - '-r', $Wallet::Config::KEYTAB_REALM, - 'get', $principal); - return (system_quiet ($Wallet::Config::KEYTAB_KADMIN, @args) == 0); + @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, + '-K', $Wallet::Config::KEYTAB_FILE, + '-r', $Wallet::Config::KEYTAB_REALM, + 'get', $principal); + return (system_quiet ($Wallet::Config::KEYTAB_KADMIN, @args) == 0); } } @@ -135,28 +135,28 @@ sub enctypes { my @enctypes; if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { - open (KLIST, '-|', 'klist', '-ke', 'keytab') - or die "cannot run klist: $!\n"; - local $_; - while () { - next unless /^ *\d+ /; - my ($string) = /\((.*)\)\s*$/; - next unless $string; - $enctype = $enctype{lc $string} || 'UNKNOWN'; - push (@enctypes, $enctype); - } - close KLIST; + open (KLIST, '-|', 'klist', '-ke', 'keytab') + or die "cannot run klist: $!\n"; + local $_; + while () { + next unless /^ *\d+ /; + my ($string) = /\((.*)\)\s*$/; + next unless $string; + $enctype = $enctype{lc $string} || 'UNKNOWN'; + push (@enctypes, $enctype); + } + close KLIST; } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { - open (KTUTIL, '-|', 'ktutil', '-k', 'keytab', 'list') - or die "cannot run ktutil: $!\n"; - local $_; - while () { - next unless /^ *\d+ /; - my ($string) = /^\s*\d+\s+(\S+)/; - next unless $string; - push (@enctypes, $string); - } - close KTUTIL; + open (KTUTIL, '-|', 'ktutil', '-k', 'keytab', 'list') + or die "cannot run ktutil: $!\n"; + local $_; + while () { + next unless /^ *\d+ /; + my ($string) = /^\s*\d+\s+(\S+)/; + next unless $string; + push (@enctypes, $string); + } + close KTUTIL; } unlink 'keytab'; return sort @enctypes; @@ -298,16 +298,15 @@ EOO is ($object->error, 'KEYTAB_TMP configuration variable not set', ' with the right error'); $Wallet::Config::KEYTAB_TMP = '.'; - SKIP: { - skip ' no kadmin program test for Heimdal', 2 - if $Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal'; - - $Wallet::Config::KEYTAB_KADMIN = '/some/nonexistent/file'; - $data = $object->get (@trace); - is ($data, undef, 'Cope with a failure to run kadmin'); - like ($object->error, qr{^cannot run /some/nonexistent/file: }, - ' with the right error'); - $Wallet::Config::KEYTAB_KADMIN = 'kadmin'; + SKIP: { + skip 'no kadmin program test for Heimdal', 2 + if $Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal'; + $Wallet::Config::KEYTAB_KADMIN = '/some/nonexistent/file'; + $data = $object->get (@trace); + is ($data, undef, 'Cope with a failure to run kadmin'); + like ($object->error, qr{^cannot run /some/nonexistent/file: }, + ' with the right error'); + $Wallet::Config::KEYTAB_KADMIN = 'kadmin'; } destroy ('wallet/one'); $data = $object->get (@trace); @@ -323,19 +322,16 @@ EOO }; ok (defined ($object), 'Creating good principal succeeds'); ok (created ('wallet/one'), ' and the principal was created'); - - SKIP: { - skip ' no kadmin program test for Heimdal', 2 - if $Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal'; - - $Wallet::Config::KEYTAB_KADMIN = '/some/nonexistent/file'; - is ($object->destroy (@trace), undef, - ' and destroying it with bad kadmin fails'); - like ($object->error, qr{^cannot run /some/nonexistent/file: }, - ' with the right error'); - $Wallet::Config::KEYTAB_KADMIN = 'kadmin'; + SKIP: { + skip 'no kadmin program test for Heimdal', 2 + if $Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal'; + $Wallet::Config::KEYTAB_KADMIN = '/some/nonexistent/file'; + is ($object->destroy (@trace), undef, + ' and destroying it with bad kadmin fails'); + like ($object->error, qr{^cannot run /some/nonexistent/file: }, + ' with the right error'); + $Wallet::Config::KEYTAB_KADMIN = 'kadmin'; } - is ($object->flag_set ('locked', @trace), 1, ' and setting locked works'); is ($object->destroy (@trace), undef, ' and destroying it fails'); is ($object->error, "cannot destroy keytab:wallet/one: object is locked", @@ -713,8 +709,10 @@ EOO # Tests for enctype restriction. SKIP: { - skip 'no keytab configuration', 36 unless (-f 't/data/test.keytab' - && $Wallet::Config::KEYTAB_KRBTYPE eq 'MIT'); + unless (-f 't/data/test.keytab' + && $Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { + skip 'no keytab configuration', 36; + } # Set up our configuration. $Wallet::Config::KEYTAB_FILE = 't/data/test.keytab'; @@ -810,7 +808,6 @@ EOO ok (defined ($keytab), ' and retrieving the keytab still works'); @values = enctypes ($keytab); is ("@values", $enctypes[0], ' and it has the right enctype'); - ok (defined ($one), ' and recreating it succeeds'); is ($one->attr ('enctypes', [ $enctypes[1] ], @trace), 1, 'Setting a different single enctype works'); @values = $one->attr ('enctypes'); @@ -819,7 +816,6 @@ EOO ok (defined ($keytab), ' and retrieving the keytab still works'); @values = enctypes ($keytab); is ("@values", $enctypes[1], ' and it has the right enctype'); - ok (defined ($one), ' and recreating it succeeds'); is ($one->attr ('enctypes', [ @enctypes[0..1] ], @trace), 1, 'Setting two enctypes works'); @values = $one->attr ('enctypes'); -- cgit v1.2.3 From 43c1420d37df58fdfc8b7e5ae229afd34a8bf070 Mon Sep 17 00:00:00 2001 From: Jon Robertson Date: Thu, 21 Jan 2010 19:08:48 -0800 Subject: Documentation additions and fixes Added documentation for the new object and acl list searches to perl/Wallet/Admin.pm and server/wallet-admin. Also fixed a POD error in perl/Wallet/Kadmin.pm's docs. --- perl/Wallet/Admin.pm | 38 ++++++++++++++++++++++++++++---------- perl/Wallet/Kadmin.pm | 2 ++ server/wallet-admin | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 78 insertions(+), 13 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Admin.pm b/perl/Wallet/Admin.pm index 701c813..c86cbba 100644 --- a/perl/Wallet/Admin.pm +++ b/perl/Wallet/Admin.pm @@ -475,12 +475,14 @@ initialize() uses C as the hostname and PRINCIPAL as the user when logging the history of the ADMIN ACL creation and for any subsequent actions on the object it returns. -=item list_acls() +=item list_acls(TYPE, SEARCH) -Returns a list of all ACLs in the database. The return value is a list of -references to pairs of ACL ID and name. For example, if there are two -ACLs in the database, one with name "ADMIN" and ID 1 and one with name -"group/admins" and ID 3, list_acls() would return: +Returns a list of all ACLs matching a search type and string in the +database, or all ACLs if no search information is given. The return value +is a list of references to pairs of ACL ID and name. For example, if +there are two ACLs in the database, one with name "ADMIN" and ID 1 and one +with name "group/admins" and ID 3, list_acls() with no arguments would +return: ([ 1, 'ADMIN' ], [ 3, 'group/admins' ]) @@ -489,12 +491,20 @@ at least one ACL, but an error can be distinguished from the odd case of a database with no ACLs by calling error(). error() is guaranteed to return the error message if there was an error and undef if there was no error. -=item list_objects() +There are currently two search types. 'empty' takes no arguments, and will +return only those acls that have no entries within them. 'entry' takes two +arguments -- an entry scheme and an entry identifier -- and will return +any ACLs with an entry that matches the given scheme and contains the +given identifier. -Returns a list of all objects in the database. The return value is a list -of references to pairs of type and name. For example, if two objects -existed in the database, both of type "keytab" and with values -"host/example.com" and "foo", list_objects() would return: +=item list_objects(TYPE, SEARCH) + +Returns a list of all objects matching a search type and string in the +database, or all objects in the database if no search information is +given. The return value is a list of references to pairs of type and +name. For example, if two objects existed in the database, both of type +"keytab" and with values "host/example.com" and "foo", list_objects() +with no arguments would return: ([ 'keytab', 'host/example.com' ], [ 'keytab', 'foo' ]) @@ -503,6 +513,14 @@ database containing no objects, the caller should call error(). error() is guaranteed to return the error message if there was an error and undef if there was no error. +There are four types of searches currently. 'type' (with a given type) +will return only those entries where the type matches the given type. +'owner', with a given owner, will only return those objects owned by the +given acl name. 'flag', with a given flag name, will only return those +items with a flag set to the given value. 'acl' operates like 'owner', +but will return only those objects that have the given acl name on any +of the possible acl settings, not just owner. + =item register_object (TYPE, CLASS) Register in the database a mapping from the object type TYPE to the class diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 200136c..0a9bd43 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -120,6 +120,8 @@ calling valid_principal on the returned object -- this method is a shortcut in case we want to check validity without creating the object and worrying about proper setup. +=back + =head1 SEE ALSO kadmin(8), Wallet::Config(3), Wallet::Object::Keytab(3), wallet-backend(8) diff --git a/server/wallet-admin b/server/wallet-admin index 01fea5c..761288d 100755 --- a/server/wallet-admin +++ b/server/wallet-admin @@ -156,10 +156,10 @@ 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 list (acls | objects) +=item list (acls | objects) [ [ ... ] ] -Returns a list of all ACLs or objects in the database. ACLs will be -listed in the form: +Returns a list of ACLs or objects in the database. ACLs will be listed +in the form: (ACL ID: ) @@ -171,6 +171,51 @@ be listed in the form: In both cases, there will be one line per ACL or object. +If no searchtype is given, all the ACLs or objects in the database will +be returned. If a searchtype (and possible search arguments) are given, +then the ACLs or objects will be limited to those that match the search. + +The currently supported object search types are: + +=over 4 + +=item list objects type + +Returns all objects of the given type. + +=item list objects flag + +Returns all objects which have the given flag set. + +=item list objects owner + +Returns all objects owned by the given ACL name. + +=item list objects acl + +Returns all objects for which the given ACL name has any permissions. +This includes those objects owned by the ACL, but also those for which the +ACL has get permissions, for example. + +=back + +The currently supported ACL search types are: + +=over 4 + +=item list acls empty + +Returns all ACLs which have no entries, generally so that abandoned ACLs +can be housekept. + +=item list acls entry + +Returns all ACLs containing an entry with given schema and identifier. +The schema is used for an exact search, while the identifier given will +match any identifier containing that text, for flexibility. + +=back + =item register (object | verifier) Registers an implementation of a wallet object or ACL verifier in the -- cgit v1.2.3 From 854063db2095fac8079260b414714d239221fdff Mon Sep 17 00:00:00 2001 From: Jon Robertson Date: Thu, 21 Jan 2010 20:53:20 -0800 Subject: Removed valid_principal as a Kadmin API function valid_principal has been removed from Wallet::Kadmin and Wallet::Kadmin::Heimdal. An accessor for it in Wallet::Object::Keytab has also been removed, as have the tests in perl/t/keytab.t for the function. It still remains within Wallet::Kadmin::MIT and is used there, but only as a private method for flagging what the kadmin command-line interface cannot handle. --- perl/Wallet/Kadmin.pm | 26 +------------------------- perl/Wallet/Kadmin/Heimdal.pm | 21 +-------------------- perl/Wallet/Object/Keytab.pm | 9 +-------- perl/t/keytab.t | 28 +++++++++++++--------------- 4 files changed, 16 insertions(+), 68 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 0a9bd43..95859a9 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -20,27 +20,12 @@ 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.02'; +$VERSION = '0.03'; ############################################################################## # Public methods ############################################################################## -# Validate a principal with a submodule's validator. We can also do this via -# creating an object with new and then running valid_principal from that, -# but there are times we might wish to run it without going through the -# object creation. -sub valid_principal { - my ($class, $principal) = @_; - if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { - require Wallet::Kadmin::MIT; - return Wallet::Kadmin::MIT->valid_principal ($principal); - } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { - require Wallet::Kadmin::Heimdal; - return Wallet::Kadmin::Heimdal->valid_principal ($principal); - } -} - # 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. @@ -111,15 +96,6 @@ Finds the proper Kerberos implementation and calls the new() constructor for that implementation's module, returning the result. If the implementation is not recognized or set, die with an error message. -=item valid_principal(PRINCIPAL) - -Finds the proper Kerberos implementation and calls its own valid_principal -method, returning the result. This tells whether a principal is valid for -that implementation. This can be achieved by using new() and then directly -calling valid_principal on the returned object -- this method is a shortcut -in case we want to check validity without creating the object and worrying -about proper setup. - =back =head1 SEE ALSO diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index a8859bf..a05362e 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -21,21 +21,12 @@ 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.01'; +$VERSION = '0.02'; ############################################################################## # kadmin Interaction ############################################################################## -# Make sure that principals are well-formed and don't contain characters that -# will cause us problems when talking to kadmin. Takes a principal and -# returns true if it's okay, false otherwise. Note that we do not permit -# realm information here. -sub valid_principal { - my ($self, $principal) = @_; - return scalar ($principal =~ m,^[\w-]+(/[\w_.-]+)?\z,); -} - # Create a Heimdal::Kadm5 client object and return it. It should load # configuration from Wallet::Config. sub kadmin_client { @@ -62,7 +53,6 @@ sub kadmin_client { # so, false otherwise. Throws an exception if an error. sub exists { my ($self, $principal) = @_; - return unless $self->valid_principal ($principal); if ($Wallet::Config::KEYTAB_REALM) { $principal .= '@' . $Wallet::Config::KEYTAB_REALM; } @@ -76,9 +66,6 @@ sub exists { # undef. sub addprinc { my ($self, $principal) = @_; - unless ($self->valid_principal ($principal)) { - die "invalid principal name $principal\n"; - } my $exists = eval { $self->exists ($principal) }; if ($Wallet::Config::KEYTAB_REALM) { @@ -117,9 +104,6 @@ sub addprinc { # error. sub ktadd { my ($self, $principal, $file, @enctypes) = @_; - unless ($self->valid_principal ($principal)) { - die "invalid principal name: $principal\n"; - } if ($Wallet::Config::KEYTAB_REALM) { $principal .= '@' . $Wallet::Config::KEYTAB_REALM; } @@ -164,9 +148,6 @@ sub ktadd { # exist, return success; we're bringing reality in line with our expectations. sub delprinc { my ($self, $principal) = @_; - unless ($self->valid_principal ($principal)) { - die "invalid principal name: $principal\n"; - } my $exists = eval { $self->exists ($principal) }; die $@ if $@; if (not $exists) { diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index a361599..092e973 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -24,7 +24,7 @@ use Wallet::Kadmin; # 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.06'; +$VERSION = '0.07'; ############################################################################## # AFS kaserver synchronization @@ -490,13 +490,6 @@ sub create { return $self; } -# Provides wrapper to individual Kadmin class's valid_principal. Here only -# to help expose for testing. -sub valid_principal { - my ($self, $principal) = @_; - return Wallet::Kadmin->valid_principal ($principal); -} - # Override destroy to delete the principal out of Kerberos as well. sub destroy { my ($self, $user, $host, $time) = @_; diff --git a/perl/t/keytab.t b/perl/t/keytab.t index 3cd77d8..7745290 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -8,7 +8,8 @@ # See LICENSE for licensing terms. use POSIX qw(strftime); -use Test::More tests => 219; +use Test::More tests => 208 +; use Wallet::Admin; use Wallet::Config; @@ -192,18 +193,6 @@ my $dbh = $admin->dbh; my $history = ''; my $date = strftime ('%Y-%m-%d %H:%M:%S', localtime $trace[2]); -# Do some white-box testing of the principal validation regex. -for my $bad (qw{service\* = host/foo+bar host/foo/bar /bar bar/ - rcmd.foo}) { - ok (! Wallet::Object::Keytab->valid_principal ($bad), - "Invalid principal name $bad"); -} -for my $good (qw{service service/foo bar foo/bar host/example.org - aservice/foo}) { - ok (Wallet::Object::Keytab->valid_principal ($good), - "Valid principal name $good"); -} - # Basic keytab creation and manipulation tests. SKIP: { skip 'no keytab configuration', 49 unless -f 't/data/test.keytab'; @@ -228,12 +217,21 @@ SKIP: { Wallet::Object::Keytab->create ('keytab', "wallet\nf", $dbh, @trace) }; is ($object, undef, 'Creating malformed principal fails'); - is ($@, "invalid principal name wallet\nf\n", ' with the right error'); + if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { + is ($@, "invalid principal name wallet\nf\n", ' with the right error'); + } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { + like ($@, qr/^error adding principal wallet\nf/, + ' with the right error'); + } $object = eval { Wallet::Object::Keytab->create ('keytab', '', $dbh, @trace) }; is ($object, undef, 'Creating empty principal fails'); - is ($@, "invalid principal name \n", ' with the right error'); + if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { + is ($@, "invalid principal name \n", ' with the right error'); + } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { + like ($@, qr/^error adding principal \@/, ' with the right error'); + } $object = eval { Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace) }; -- cgit v1.2.3 From 04b875599b1d4559dbcd356726035416081c6b48 Mon Sep 17 00:00:00 2001 From: Jon Robertson Date: Thu, 28 Jan 2010 00:07:16 -0800 Subject: Improved and fixed tests related to Pod and KDC type Added a fix to the Pod tests to change the order of the arguments in a skip statement to the correct order. Also added tests for the KEYTAB_KRBTYPE value in the keytab tests, and changed the Wallet::Kadmin module to standardize the errors returned with no keytab set and add new error for keytab set but not a valid value. --- perl/Wallet/Kadmin.pm | 5 ++++- perl/t/keytab.t | 23 ++++++++++++++++++++--- tests/server/pod-t.in | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 95859a9..501bc37 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -32,7 +32,10 @@ $VERSION = '0.03'; sub new { my ($class) = @_; my ($kadmin); - if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { + if (!defined $Wallet::Config::KEYTAB_KRBTYPE + || !$Wallet::Config::KEYTAB_KRBTYPE) { + die "keytab object implementation not configured\n"; + } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { require Wallet::Kadmin::MIT; $kadmin = Wallet::Kadmin::MIT->new (); } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { diff --git a/perl/t/keytab.t b/perl/t/keytab.t index 7745290..ab5b19d 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -8,7 +8,7 @@ # See LICENSE for licensing terms. use POSIX qw(strftime); -use Test::More tests => 208 +use Test::More tests => 212 ; use Wallet::Admin; @@ -387,6 +387,21 @@ EOO is ($@, "keytab object implementation not configured\n", ' with the right error'); $Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm'); + undef $Wallet::Config::KEYTAB_KRBTYPE; + $object = eval { + Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace) + }; + is ($object, undef, ' and another'); + is ($@, "keytab object implementation not configured\n", + ' with the right error'); + $Wallet::Config::KEYTAB_KRBTYPE = 'Active Directory'; + $object = eval { + Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace) + }; + is ($object, undef, ' and one set to an invalid value'); + is ($@, "keytab krb server type not set to a valid value\n", + ' with the right error'); + $Wallet::Config::KEYTAB_KRBTYPE = contents ('t/data/test.krbtype'); } # Tests for unchanging support. Skip these if we don't have a keytab or if we @@ -403,6 +418,7 @@ SKIP: { $Wallet::Config::KEYTAB_FILE = 't/data/test.keytab'; $Wallet::Config::KEYTAB_PRINCIPAL = contents ('t/data/test.principal'); $Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm'); + $Wallet::Config::KEYTAB_KRBTYPE = contents ('t/data/test.krbtype'); $Wallet::Config::KEYTAB_TMP = '.'; my $realm = $Wallet::Config::KEYTAB_REALM; my $principal = $Wallet::Config::KEYTAB_PRINCIPAL; @@ -581,6 +597,7 @@ EOO $Wallet::Config::KEYTAB_FILE = 't/data/test.keytab'; $Wallet::Config::KEYTAB_PRINCIPAL = contents ('t/data/test.principal'); $Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm'); + $Wallet::Config::KEYTAB_KRBTYPE = contents ('t/data/test.krbtype'); $Wallet::Config::KEYTAB_TMP = '.'; $Wallet::Config::KEYTAB_AFS_KASETKEY = '../kasetkey/kasetkey'; my $realm = $Wallet::Config::KEYTAB_REALM; @@ -707,8 +724,7 @@ EOO # Tests for enctype restriction. SKIP: { - unless (-f 't/data/test.keytab' - && $Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { + unless (-f 't/data/test.keytab') { skip 'no keytab configuration', 36; } @@ -716,6 +732,7 @@ SKIP: { $Wallet::Config::KEYTAB_FILE = 't/data/test.keytab'; $Wallet::Config::KEYTAB_PRINCIPAL = contents ('t/data/test.principal'); $Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm'); + $Wallet::Config::KEYTAB_KRBTYPE = contents ('t/data/test.krbtype'); $Wallet::Config::KEYTAB_TMP = '.'; my $realm = $Wallet::Config::KEYTAB_REALM; my $principal = $Wallet::Config::KEYTAB_PRINCIPAL; diff --git a/tests/server/pod-t.in b/tests/server/pod-t.in index 4973d23..4575ecb 100644 --- a/tests/server/pod-t.in +++ b/tests/server/pod-t.in @@ -15,7 +15,7 @@ plan tests => $total; eval 'use Test::Pod 1.00'; SKIP: { - skip $total, 'Test::Pod 1.00 required for testing POD' if $@; + skip 'Test::Pod 1.00 required for testing POD', $total if $@; for my $file (@files) { pod_file_ok ("@abs_top_srcdir@/server/$file", "server/$file"); } -- cgit v1.2.3 From 346660359be7666e8629c14b2d12cebf794f6f26 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Mon, 8 Feb 2010 15:47:04 -0800 Subject: Coding style and whitespace fixes Combine a long series of eval blocks into a single block and a single error check. Remove trailing whitespace, and in some cases remove trailing () on method calls where the parens aren't useful. --- perl/Wallet/Admin.pm | 28 +++++++++--------- perl/Wallet/Kadmin.pm | 7 ++--- perl/Wallet/Kadmin/Heimdal.pm | 68 +++++++++++++++---------------------------- perl/Wallet/Object/Keytab.pm | 2 +- perl/t/kadmin.t | 6 ++-- perl/t/keytab.t | 2 +- server/wallet-admin | 6 ++-- 7 files changed, 49 insertions(+), 70 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Admin.pm b/perl/Wallet/Admin.pm index c86cbba..ff87b94 100644 --- a/perl/Wallet/Admin.pm +++ b/perl/Wallet/Admin.pm @@ -477,11 +477,11 @@ actions on the object it returns. =item list_acls(TYPE, SEARCH) -Returns a list of all ACLs matching a search type and string in the -database, or all ACLs if no search information is given. The return value -is a list of references to pairs of ACL ID and name. For example, if -there are two ACLs in the database, one with name "ADMIN" and ID 1 and one -with name "group/admins" and ID 3, list_acls() with no arguments would +Returns a list of all ACLs matching a search type and string in the +database, or all ACLs if no search information is given. The return value +is a list of references to pairs of ACL ID and name. For example, if +there are two ACLs in the database, one with name "ADMIN" and ID 1 and one +with name "group/admins" and ID 3, list_acls() with no arguments would return: ([ 1, 'ADMIN' ], [ 3, 'group/admins' ]) @@ -492,18 +492,18 @@ database with no ACLs by calling error(). error() is guaranteed to return the error message if there was an error and undef if there was no error. There are currently two search types. 'empty' takes no arguments, and will -return only those acls that have no entries within them. 'entry' takes two -arguments -- an entry scheme and an entry identifier -- and will return +return only those acls that have no entries within them. 'entry' takes two +arguments -- an entry scheme and an entry identifier -- and will return any ACLs with an entry that matches the given scheme and contains the given identifier. =item list_objects(TYPE, SEARCH) -Returns a list of all objects matching a search type and string in the -database, or all objects in the database if no search information is -given. The return value is a list of references to pairs of type and -name. For example, if two objects existed in the database, both of type -"keytab" and with values "host/example.com" and "foo", list_objects() +Returns a list of all objects matching a search type and string in the +database, or all objects in the database if no search information is +given. The return value is a list of references to pairs of type and +name. For example, if two objects existed in the database, both of type +"keytab" and with values "host/example.com" and "foo", list_objects() with no arguments would return: ([ 'keytab', 'host/example.com' ], [ 'keytab', 'foo' ]) @@ -516,8 +516,8 @@ if there was no error. There are four types of searches currently. 'type' (with a given type) will return only those entries where the type matches the given type. 'owner', with a given owner, will only return those objects owned by the -given acl name. 'flag', with a given flag name, will only return those -items with a flag set to the given value. 'acl' operates like 'owner', +given acl name. 'flag', with a given flag name, will only return those +items with a flag set to the given value. 'acl' operates like 'owner', but will return only those objects that have the given acl name on any of the possible acl settings, not just owner. diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 501bc37..b3a630e 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -32,15 +32,14 @@ $VERSION = '0.03'; sub new { my ($class) = @_; my ($kadmin); - if (!defined $Wallet::Config::KEYTAB_KRBTYPE - || !$Wallet::Config::KEYTAB_KRBTYPE) { + if (not $Wallet::Config::KEYTAB_KRBTYPE) { die "keytab object implementation not configured\n"; } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { require Wallet::Kadmin::MIT; - $kadmin = Wallet::Kadmin::MIT->new (); + $kadmin = Wallet::Kadmin::MIT->new; } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { require Wallet::Kadmin::Heimdal; - $kadmin = Wallet::Kadmin::Heimdal->new (); + $kadmin = Wallet::Kadmin::Heimdal->new; } else { die "keytab krb server type not set to a valid value\n"; } diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index b0010a5..d046162 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -98,40 +98,27 @@ sub addprinc { my $exists = eval { $self->exists ($principal) }; if ($@) { $self->error ("error adding principal $principal: $@"); - return undef; + return; } return 1 if $exists; # The way Heimdal::Kadm5 works, we create a principal object, create the # actual principal set inactive, then randomize it and activate it. + # # TODO - Paranoia makes me want to set the password to something random # on creation even if it is inactive until after randomized by # module. my $kadmin = $self->{client}; - my $princdata = eval { $kadmin->makePrincipal ($principal) }; - if ($@) { - $self->error ("error adding principal $principal: $@"); - return; - } - - # Disable the principal before creating, until we've randomized the - # password. - my $attrs = eval { $princdata->getAttributes }; - if ($@) { - $self->error ("error adding principal $principal: $@"); - return; + eval { + my $princdata = $kadmin->makePrincipal ($principal); + my $attrs = $princdata->getAttributes; + $attrs |= KRB5_KDB_DISALLOW_ALL_TIX; + $princdata->setAttributes ($attrs); + my $password = 'inactive'; + $kadmin->createPrincipal ($princdata, $password, 0); + $kadmin->randKeyPrincipal ($principal); + $kadmin->enablePrincipal ($principal); } - $attrs |= KRB5_KDB_DISALLOW_ALL_TIX; - eval { $princdata->setAttributes ($attrs) }; - if ($@) { - $self->error ("error adding principal $principal: $@"); - return; - } - - my $password = 'inactive'; - my $test = eval { $kadmin->createPrincipal ($princdata, $password, 0) }; - eval { $kadmin->randKeyPrincipal ($principal) } unless $@; - eval { $kadmin->enablePrincipal ($principal) } unless $@; if ($@) { $self->error ("error adding principal $principal: $@"); return; @@ -156,8 +143,8 @@ sub ktadd { my $kadmin = $self->{client}; eval { $kadmin->randKeyPrincipal ($principal) }; if ($@) { - $self->error ("error creating keytab for $principal: could not " - ."reinit enctypes: $@"); + $self->error ("error creating keytab for $principal: could not" + . " reinit enctypes: $@"); return; } my $princdata = eval { $kadmin->getPrincipal ($principal) }; @@ -165,23 +152,22 @@ sub ktadd { $self->error ("error creating keytab for $principal: $@"); return; } elsif (!$princdata) { - $self->error ("error creating keytab for $principal: principal does " - ."not exist"); + $self->error ("error creating keytab for $principal: principal does" + . " not exist"); return; } # Now actually remove any non-requested enctypes, if we requested any. if (@enctypes) { - my (%wanted); - my $alltypes = $princdata->getKeytypes (); - foreach (@enctypes) { $wanted{$_} = 1 } - foreach my $key (@{$alltypes}) { - my $keytype = ${$key}[0]; + my $alltypes = $princdata->getKeytypes; + my %wanted = map { $_ => 1 } @enctypes; + for my $key (@{ $alltypes }) { + my $keytype = $key->[0]; next if exists $wanted{$keytype}; eval { $princdata->delKeytypes ($keytype) }; if ($@) { - $self->error ("error removing keytype $keytype from the ". - "keytab: $@"); + $self->error ("error removing keytype $keytype from the" + . " keytab: $@"); return; } } @@ -192,12 +178,12 @@ sub ktadd { } } + # Create the keytab. eval { $kadmin->extractKeytab ($princdata, $file) }; if ($@) { $self->error ("error creating keytab for principal: $@"); return; } - return 1; } @@ -226,20 +212,14 @@ sub delprinc { return 1; } -############################################################################## -# Documentation -############################################################################## - -# Create a new MIT kadmin object. Very empty for the moment, but later it -# will probably fill out if we go to using a module rather than calling -# kadmin directly. +# Create a new Heimdal kadmin object. sub new { my ($class) = @_; my $self = { client => undef, }; bless ($self, $class); - $self->{client} = kadmin_client (); + $self->{client} = $self->kadmin_client; return $self; } diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index 22598f1..9fece80 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -497,7 +497,7 @@ sub create { if (not $kadmin->addprinc ($name)) { die $kadmin->error, "\n"; - } + } $self = $class->SUPER::create ($type, $name, $dbh, $creator, $host, $time); $self->{kadmin} = $kadmin; return $self; diff --git a/perl/t/kadmin.t b/perl/t/kadmin.t index 96b249b..18d452e 100755 --- a/perl/t/kadmin.t +++ b/perl/t/kadmin.t @@ -29,7 +29,7 @@ use Util; # We test a Wallet::Kadmin::* module's actual workings in the keytab.t tests. # The only things we want to test here are that each module is found, that -# Wallet::Kadmin itself delegates to them, and that the private MIT principal +# Wallet::Kadmin itself delegates to them, and that the private MIT principal # validation works as it should. for my $bad (qw{service\* = host/foo+bar host/foo/bar /bar bar/ rcmd.foo}) { @@ -44,7 +44,7 @@ for my $good (qw{service service/foo bar foo/bar host/example.org # Test creating an MIT object and seeing if the callback works. $Wallet::Config::KEYTAB_KRBTYPE = 'MIT'; -my $kadmin = Wallet::Kadmin->new (); +my $kadmin = Wallet::Kadmin->new; ok (defined ($kadmin), 'MIT kadmin object created'); my $callback = sub { return 1 }; $kadmin->fork_callback ($callback); @@ -64,6 +64,6 @@ SKIP: { undef $Wallet::Config::KEYTAB_REALM; undef $kadmin; $Wallet::Config::KEYTAB_KRBTYPE = 'Heimdal'; - $kadmin = eval { Wallet::Kadmin->new () }; + $kadmin = eval { Wallet::Kadmin->new }; is ($kadmin, undef, 'Heimdal fails properly.'); } diff --git a/perl/t/keytab.t b/perl/t/keytab.t index ab5b19d..d1d5ba6 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -220,7 +220,7 @@ SKIP: { if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { is ($@, "invalid principal name wallet\nf\n", ' with the right error'); } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { - like ($@, qr/^error adding principal wallet\nf/, + like ($@, qr/^error adding principal wallet\nf/, ' with the right error'); } $object = eval { diff --git a/server/wallet-admin b/server/wallet-admin index 761288d..cd775b6 100755 --- a/server/wallet-admin +++ b/server/wallet-admin @@ -158,7 +158,7 @@ used, the database may also have to be created in advance. =item list (acls | objects) [ [ ... ] ] -Returns a list of ACLs or objects in the database. ACLs will be listed +Returns a list of ACLs or objects in the database. ACLs will be listed in the form: (ACL ID: ) @@ -210,8 +210,8 @@ can be housekept. =item list acls entry -Returns all ACLs containing an entry with given schema and identifier. -The schema is used for an exact search, while the identifier given will +Returns all ACLs containing an entry with given schema and identifier. +The schema is used for an exact search, while the identifier given will match any identifier containing that text, for flexibility. =back -- cgit v1.2.3 From b037770195ef0bd98d6655a65873b25d90e36032 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Tue, 9 Feb 2010 13:14:41 -0800 Subject: Document and make case-insensitive KEYTAB_KRBTYPE KEYTAB_KRBTYPE wasn't documented in Wallet::Config. Add it and the variable declaration. Also document the new mandatory setting in NEWS and add the Heimdal::Kadm5 requirement to README. Remove some of the language in README that implies that only MIT Kerberos is supported. Make the setting case-insensitive and improve the error message from Wallet::Kadmin if it isn't set. --- NEWS | 8 ++++++-- README | 18 +++++++----------- perl/Wallet/Config.pm | 9 +++++++++ perl/Wallet/Kadmin.pm | 9 +++++---- 4 files changed, 27 insertions(+), 17 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/NEWS b/NEWS index 3185db3..c6b3a9d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,12 @@ wallet 0.10 (unreleased) + Add support for Heimdal KDCs as well as MIT Kerberos KDCs. There is + now a mandatory new setting in Wallet::Config: $KEYTAB_KRBTYPE. It + should be set to either "MIT" or "Heimdal" depending on the Kerberos + KDC implementation used. The Heimdal support requires the + Heimdal::Kadm5 Perl module. + Remove kaserver synchronization support. It is no longer tested, and retaining the code was increasing the complexity of wallet, and some specific requirements (such as different realm names between kaserver @@ -28,8 +34,6 @@ wallet 0.10 (unreleased) Report ACL names as well as numbers in object history. - Add support for Heimdal KDCs as well as MIT Kerberos KDCs. - wallet 0.9 (2008-04-24) The wallet command-line client now reads the data for store from a diff --git a/README b/README index fa99b18..6e165ec 100644 --- a/README +++ b/README @@ -88,12 +88,13 @@ REQUIREMENTS Perl module, which comes with recent versions of Perl and is available on CPAN for older versions. - The keytab support in the wallet server requires the kadmin client - program be installed and currently assumes that it follows the syntax of - the MIT Kerberos kadmin client. It also requires that the wallet server - have a keytab for a principal with appropriate access to create, modify, - and delete principals from the KDC (as configured in kadm5.acl on an MIT - Kerberos KDC). + The keytab support in the wallet server supports either Heimdal or MIT + Kerberos KDCs. The Heimdal support requires the Heimdal::Kadm5 Perl + module. The MIT Kerberos support requires the MIT Kerberos kadmin + client program be installed. In either case, wallet also requires that + the wallet server have a keytab for a principal with appropriate access + to create, modify, and delete principals from the KDC (as configured in + kadm5.acl on an MIT Kerberos KDC). To support the unchanging flag on keytab objects, the Net::Remctl Perl module (shipped with remctl) must be installed on the server and the @@ -106,11 +107,6 @@ REQUIREMENTS to manage DNS), the Net::Remctl Perl module must be installed on the server. - To support synchronization with an AFS kaserver, the server must have - the Authen::Krb5 Perl module installed. AFS kaserver synchronization - support also requires building kasetkey, which requires AFS and Kerberos - v4 libraries. - To run the test suite, you must have Perl 5.8 or later and the Perl DBI module installed. You will also need a DBD module installed for the database backend you want to use (currently, either DBD::SQLite or diff --git a/perl/Wallet/Config.pm b/perl/Wallet/Config.pm index 7198c07..ae8cf9c 100644 --- a/perl/Wallet/Config.pm +++ b/perl/Wallet/Config.pm @@ -250,6 +250,15 @@ default PATH. our $KEYTAB_KADMIN = 'kadmin'; +=item KEYTAB_KRBTYPE + +The Kerberos KDC implementation type, either C or C +(case-insensitive). KEYTAB_KRBTYPE must be set to use keytab objects. + +=cut + +our $KEYTAB_KRBTYPE; + =item KEYTAB_PRINCIPAL The principal whose key is stored in KEYTAB_FILE. The wallet will diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index b3a630e..5c01ee3 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -1,7 +1,7 @@ # Wallet::Kadmin -- Kadmin module wrapper for the wallet. # # Written by Jon Robertson -# Copyright 2009 Board of Trustees, Leland Stanford Jr. University +# Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -34,14 +34,15 @@ sub new { my ($kadmin); if (not $Wallet::Config::KEYTAB_KRBTYPE) { die "keytab object implementation not configured\n"; - } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') { + } elsif (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'mit') { require Wallet::Kadmin::MIT; $kadmin = Wallet::Kadmin::MIT->new; - } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') { + } elsif (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'heimdal') { require Wallet::Kadmin::Heimdal; $kadmin = Wallet::Kadmin::Heimdal->new; } else { - die "keytab krb server type not set to a valid value\n"; + my $type = $Wallet::Config::KEYTAB_KRBTYPE; + die "unknown KEYTAB_KRBTYPE setting: $type\n"; } return $kadmin; -- cgit v1.2.3 From cbdc17af5f7a772188638f0057fffd357acbbd38 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Tue, 9 Feb 2010 13:41:11 -0800 Subject: Use the long enctype name for aes256-cts-hmac-sha1-96 Heimdal requires the full name and doesn't support the short name that MIT has as an alias. Change the documentation to use the long name uniformly. --- client/wallet.pod | 6 +++--- perl/Wallet/Kadmin.pm | 2 +- perl/Wallet/Kadmin/Heimdal.pm | 16 ++++++++-------- perl/Wallet/Kadmin/MIT.pm | 14 ++++++++------ server/wallet-backend | 6 +++--- 5 files changed, 23 insertions(+), 21 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/client/wallet.pod b/client/wallet.pod index 6451e72..9908bb1 100644 --- a/client/wallet.pod +++ b/client/wallet.pod @@ -374,9 +374,9 @@ Keytab objects support the following attributes: Restricts the generated keytab to a specific set of encryption types. The values of this attribute must be enctype strings recognized by Kerberos -(strings like C or C). Note that the salt should -not be included; since the salt is irrelevant for keytab keys, it will -always be set to C by the wallet. +(strings like C or C). Note that +the salt should not be included; since the salt is irrelevant for keytab +keys, it will always be set to C by the wallet. If this attribute is set, the specified enctype list will be passed to ktadd when get() is called for that keytab. If it is not set, the default set in diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 5c01ee3..65ddf4b 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -63,7 +63,7 @@ Wallet::Kadmin - Kadmin module wrapper for wallet keytabs my $kadmin = Wallet::Kadmin->new (); $kadmin->addprinc ("host/shell.example.com"); - $kadmin->ktadd ("host/shell.example.com", "aes256-cts"); + $kadmin->ktadd ("host/shell.example.com", "aes256-cts-hmac-sha1-96"); my $exists = $kadmin->exists ("host/oldshell.example.com"); $kadmin->delprinc ("host/oldshell.example.com") if $exists; diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index 2ca8dcd..428202b 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -1,7 +1,7 @@ # Wallet::Kadmin::Heimdal -- Heimdal Kadmin interactions for the wallet. # # Written by Jon Robertson -# Copyright 2009 Board of Trustees, Leland Stanford Jr. University +# Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -238,7 +238,7 @@ Wallet::Kadmin::MIT - MIT admin interactions for wallet keytabs my $kadmin = Wallet::Kadmin::MIT->new (); $kadmin->addprinc ("host/shell.example.com"); - $kadmin->ktadd ("host/shell.example.com", "aes256-cts"); + $kadmin->ktadd ("host/shell.example.com", "aes256-cts-hmac-sha1-96"); my $exists = $kadmin->exists ("host/oldshell.example.com"); $kadmin->delprinc ("host/oldshell.example.com") if $exists; @@ -282,10 +282,11 @@ reality. =item ktadd(PRINCIPAL, FILE, ENCTYPES) -Creates a new keytab for the given principal, as the given file, limited to -the enctypes supplied. The enctype values must be enctype strings recognized -by Kerberos (strings like C or C). An error is -thrown on failure or if the creation fails, otherwise true is returned. +Creates a new keytab for the given principal, as the given file, limited +to the enctypes supplied. The enctype values must be enctype strings +recognized by Kerberos (strings like C or +C). An error is thrown on failure or if the creation fails, +otherwise true is returned. =back @@ -305,7 +306,6 @@ from L. =head1 AUTHORS -Russ Allbery -Jon Robertson +Russ Allbery and Jon Robertson . =cut diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index c3ad901..49691b0 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -2,7 +2,8 @@ # # Written by Russ Allbery # Pulled into a module by Jon Robertson -# Copyright 2007, 2008, 2009 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2009, 2010 +# Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -233,7 +234,7 @@ Wallet::Kadmin::MIT - MIT admin interactions for wallet keytabs my $kadmin = Wallet::Kadmin::MIT->new (); $kadmin->addprinc ("host/shell.example.com"); - $kadmin->ktadd ("host/shell.example.com", "aes256-cts"); + $kadmin->ktadd ("host/shell.example.com", "aes256-cts-hmac-sha1-96"); my $exists = $kadmin->exists ("host/oldshell.example.com"); $kadmin->delprinc ("host/oldshell.example.com") if $exists; @@ -277,10 +278,11 @@ reality. =item ktadd(PRINCIPAL, FILE, ENCTYPES) -Creates a new keytab for the given principal, as the given file, limited to -the enctypes supplied. The enctype values must be enctype strings recognized -by Kerberos (strings like C or C). An error is -thrown on failure or if the creation fails, otherwise true is returned. +Creates a new keytab for the given principal, as the given file, limited +to the enctypes supplied. The enctype values must be enctype strings +recognized by Kerberos (strings like C or +C). An error is thrown on failure or if the creation fails, +otherwise true is returned. =back diff --git a/server/wallet-backend b/server/wallet-backend index 448f175..2b58255 100755 --- a/server/wallet-backend +++ b/server/wallet-backend @@ -558,9 +558,9 @@ Keytab objects support the following attributes: Restricts the generated keytab to a specific set of encryption types. The values of this attribute must be enctype strings recognized by Kerberos -(strings like C or C). Note that the salt should -not be included; since the salt is irrelevant for keytab keys, it will -always be set to C by the wallet. +(strings like C or C). Note that +the salt should not be included; since the salt is irrelevant for keytab +keys, it will always be set to C by the wallet. If this attribute is set, the specified enctype list will be passed to ktadd when get() is called for that keytab. If it is not set, the default set in -- cgit v1.2.3 From ae02de1488068b84371b05842c81a9aecc5f24c4 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Tue, 9 Feb 2010 23:19:27 -0800 Subject: Check spelling of server API POD and tweak server docs Also update the POD syntax check to the current version of that check I use elsewhere. Since I'm touching all the POD anyway, also rewrap all of the POD to 74 columns. Fix some references to MIT in the Wallet::Kadmin::Heimdal module documentation. --- perl/Wallet/ACL.pm | 110 +++++++++++----------- perl/Wallet/ACL/Base.pm | 31 ++++--- perl/Wallet/ACL/Krb5.pm | 13 ++- perl/Wallet/ACL/NetDB.pm | 26 +++--- perl/Wallet/ACL/NetDB/Root.pm | 46 +++++----- perl/Wallet/Admin.pm | 39 ++++---- perl/Wallet/Config.pm | 196 ++++++++++++++++++++------------------- perl/Wallet/Database.pm | 17 ++-- perl/Wallet/Kadmin.pm | 31 ++++--- perl/Wallet/Kadmin/Heimdal.pm | 52 +++++------ perl/Wallet/Kadmin/MIT.pm | 45 ++++----- perl/Wallet/Object/Base.pm | 209 ++++++++++++++++++++++-------------------- perl/Wallet/Object/File.pm | 18 ++-- perl/Wallet/Object/Keytab.pm | 55 ++++++----- perl/Wallet/Schema.pm | 129 ++++++++++++++------------ perl/Wallet/Server.pm | 209 ++++++++++++++++++++++-------------------- perl/t/pod-spelling.t | 75 +++++++++++++++ perl/t/pod.t | 14 ++- 18 files changed, 731 insertions(+), 584 deletions(-) create mode 100755 perl/t/pod-spelling.t (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/ACL.pm b/perl/Wallet/ACL.pm index 9136fc2..76e7354 100644 --- a/perl/Wallet/ACL.pm +++ b/perl/Wallet/ACL.pm @@ -1,7 +1,7 @@ # Wallet::ACL -- Implementation of ACLs in the wallet system. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -21,7 +21,7 @@ use POSIX qw(strftime); # 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.05'; +$VERSION = '0.06'; ############################################################################## # Constructors @@ -427,6 +427,9 @@ __END__ Wallet::ACL - Implementation of ACLs in the wallet system +=for stopwords +ACL DBH metadata HOSTNAME DATETIME timestamp Allbery + =head1 SYNOPSIS my $acl = Wallet::ACL->create ('group:sysadmin'); @@ -445,22 +448,22 @@ Wallet::ACL - Implementation of ACLs in the wallet system =head1 DESCRIPTION -Wallet::ACL implements the ACL system for the wallet: the methods to create, -find, rename, and destroy ACLs; the methods to add and remove entries from -an ACL; and the methods to list the contents of an ACL and check a principal -against it. +Wallet::ACL implements the ACL system for the wallet: the methods to +create, find, rename, and destroy ACLs; the methods to add and remove +entries from an ACL; and the methods to list the contents of an ACL and +check a principal against it. An ACL is a list of zero or more ACL entries, each of which consists of a -scheme and an identifier. Each scheme is associated with a verifier module -that checks Kerberos principals against identifiers for that scheme and -returns whether the principal should be permitted access by that identifier. -The interpretation of the identifier is entirely left to the scheme. This -module maintains the ACLs and dispatches check operations to the appropriate -verifier module. - -Each ACL is identified by a human-readable name and a persistant unique -numeric identifier. The numeric identifier (ID) should be used to refer to -the ACL so that it can be renamed as needed without breaking external +scheme and an identifier. Each scheme is associated with a verifier +module that checks Kerberos principals against identifiers for that scheme +and returns whether the principal should be permitted access by that +identifier. The interpretation of the identifier is entirely left to the +scheme. This module maintains the ACLs and dispatches check operations to +the appropriate verifier module. + +Each ACL is identified by a human-readable name and a persistent unique +numeric identifier. The numeric identifier (ID) should be used to refer +to the ACL so that it can be renamed as needed without breaking external references. =head1 CLASS METHODS @@ -481,8 +484,8 @@ finding an existing one, creates a new ACL record in the database with the given NAME. NAME must not be all-numeric, since that would conflict with the automatically assigned IDs. Returns the new object on success and throws an exception on failure. PRINCIPAL, HOSTNAME, and DATETIME are -stored as history information. PRINCIPAL should be the user who is creating -the ACL. If DATETIME isn't given, the current time is used. +stored as history information. PRINCIPAL should be the user who is +creating the ACL. If DATETIME isn't given, the current time is used. =back @@ -492,42 +495,43 @@ the ACL. If DATETIME isn't given, the current time is used. =item add(SCHEME, INSTANCE, PRINCIPAL, HOSTNAME [, DATETIME]) -Add the given ACL entry (given by SCHEME and INSTANCE) to this ACL. Returns -true on success and false on failure. On failure, the caller should call -error() to get the error message. PRINCIPAL, HOSTNAME, and DATETIME are -stored as history information. PRINCIPAL should be the user who is adding -the ACL entry. If DATETIME isn't given, the current time is used. +Add the given ACL entry (given by SCHEME and INSTANCE) to this ACL. +Returns true on success and false on failure. On failure, the caller +should call error() to get the error message. PRINCIPAL, HOSTNAME, and +DATETIME are stored as history information. PRINCIPAL should be the user +who is adding the ACL entry. If DATETIME isn't given, the current time is +used. =item check(PRINCIPAL) Checks whether the given PRINCIPAL should be allowed access given ACL. Returns 1 if access was granted, 0 if access is declined, and undef on -error. On error, the caller should call error() to get the error text. Any -errors found by the individual ACL verifiers can be retrieved by calling -check_errors(). Errors from individual ACL verifiers will not result in an -error return from check(); instead, the check will continue with the next -entry in the ACL. +error. On error, the caller should call error() to get the error text. +Any errors found by the individual ACL verifiers can be retrieved by +calling check_errors(). Errors from individual ACL verifiers will not +result in an error return from check(); instead, the check will continue +with the next entry in the ACL. check() returns success as soon as an entry in the ACL grants access to PRINCIPAL. There is no provision for negative ACLs or exceptions. =item check_errors() -Return (as a list in array context and a string with newlines between errors -and at the end of the last error in scalar context) the errors, if any, -returned by ACL verifiers for the last check operation. If there were no -errors from the last check() operation, returns the empty list in array -context and undef in scalar context. +Return (as a list in array context and a string with newlines between +errors and at the end of the last error in scalar context) the errors, if +any, returned by ACL verifiers for the last check operation. If there +were no errors from the last check() operation, returns the empty list in +array context and undef in scalar context. =item destroy(PRINCIPAL, HOSTNAME [, DATETIME]) Destroys this ACL from the database. Note that this will fail due to integrity constraint errors if the ACL is still referenced by any object; -the ACL must be removed from all objects first. Returns true on success and -false on failure. On failure, the caller should call error() to get the -error message. PRINCIPAL, HOSTNAME, and DATETIME are stored as history -information. PRINCIPAL should be the user who is destroying the ACL. If -DATETIME isn't given, the current time is used. +the ACL must be removed from all objects first. Returns true on success +and false on failure. On failure, the caller should call error() to get +the error message. PRINCIPAL, HOSTNAME, and DATETIME are stored as +history information. PRINCIPAL should be the user who is destroying the +ACL. If DATETIME isn't given, the current time is used. =item error() @@ -542,7 +546,8 @@ 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. On failure, -returns undef, and the caller should call error() to get the error message. +returns undef, and the caller should call error() to get the error +message. =item id() @@ -569,28 +574,29 @@ Returns the human-readable name of this ACL. =item remove(SCHEME, INSTANCE, PRINCIPAL, HOSTNAME [, DATETIME]) Remove the given ACL line (given by SCHEME and INSTANCE) from this ACL. -Returns true on success and false on failure. On failure, the caller should -call error() to get the error message. PRINCIPAL, HOSTNAME, and DATETIME -are stored as history information. PRINCIPAL should be the user who is -removing the ACL entry. If DATETIME isn't given, the current time is used. +Returns true on success and false on failure. On failure, the caller +should call error() to get the error message. PRINCIPAL, HOSTNAME, and +DATETIME are stored as history information. PRINCIPAL should be the user +who is removing the ACL entry. If DATETIME isn't given, the current time +is used. =item rename(NAME) Rename this ACL. This changes the name used for human convenience but not the system-generated ACL ID that is used to reference this ACL. The new NAME must not be all-numeric, since that would conflict with -system-generated ACL IDs. Returns true on success and false on failure. On -failure, the caller should call error() to get the error message. +system-generated ACL IDs. Returns true on success and false on failure. +On failure, the caller should call error() to get the error message. Note that rename() operations are not logged in the ACL history. =item show() -Returns a human-readable description of this ACL, including its membership. -This method should only be used for display of the ACL to humans. Use the -list(), name(), and id() methods instead to get ACL information for use in -other code. On failure, returns undef, and the caller should call error() -to get the error message. +Returns a human-readable description of this ACL, including its +membership. This method should only be used for display of the ACL to +humans. Use the list(), name(), and id() methods instead to get ACL +information for use in other code. On failure, returns undef, and the +caller should call error() to get the error message. =back @@ -598,8 +604,8 @@ to get the error message. Wallet::ACL::Base(3), wallet-backend(8) -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/Wallet/ACL/Base.pm b/perl/Wallet/ACL/Base.pm index 004de75..9a8a3cb 100644 --- a/perl/Wallet/ACL/Base.pm +++ b/perl/Wallet/ACL/Base.pm @@ -1,7 +1,7 @@ # Wallet::ACL::Base -- Parent class for wallet ACL verifiers. # # Written by Russ Allbery -# Copyright 2007 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -18,7 +18,7 @@ use vars qw($VERSION); # 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.01'; +$VERSION = '0.02'; ############################################################################## # Interface @@ -59,6 +59,9 @@ __END__ # Documentation ############################################################################## +=for stopwords +ACL Allbery + =head1 NAME Wallet::ACL::Base - Generic parent class for wallet ACL verifiers @@ -74,9 +77,9 @@ Wallet::ACL::Base - Generic parent class for wallet ACL verifiers =head1 DESCRIPTION -Wallet::ACL::Base is the generic parent class for wallet ACL verifiers. It -provides default functions and behavior and all ACL verifiers should inherit -from it. It is not used directly. +Wallet::ACL::Base is the generic parent class for wallet ACL verifiers. +It provides default functions and behavior and all ACL verifiers should +inherit from it. It is not used directly. =head1 METHODS @@ -84,8 +87,8 @@ from it. It is not used directly. =item new() -Creates a new ACL verifier. The generic function provided here just creates -and blesses an object. +Creates a new ACL verifier. The generic function provided here just +creates and blesses an object. =item check(PRINCIPAL, ACL) @@ -99,11 +102,11 @@ 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> 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. +one or more error strings. If so, those strings are concatenated +together, trailing newlines are removed, any text of the form S> 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. =back @@ -111,8 +114,8 @@ string. Wallet::ACL(3), wallet-backend(8) -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/Wallet/ACL/Krb5.pm b/perl/Wallet/ACL/Krb5.pm index 1c584c5..496fcf0 100644 --- a/perl/Wallet/ACL/Krb5.pm +++ b/perl/Wallet/ACL/Krb5.pm @@ -1,7 +1,7 @@ # Wallet::ACL::Krb5 -- Wallet Kerberos v5 principal ACL verifier. # # Written by Russ Allbery -# Copyright 2007 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -22,7 +22,7 @@ use Wallet::ACL::Base; # 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.01'; +$VERSION = '0.02'; ############################################################################## # Interface @@ -50,6 +50,9 @@ __END__ # Documentation ############################################################################## +=for stopwords +ACL krb5 Allbery + =head1 NAME Wallet::ACL::Krb5 - Simple wallet ACL verifier for Kerberos principals @@ -69,7 +72,7 @@ Wallet::ACL::Krb5 - Simple wallet ACL verifier for Kerberos principals =head1 DESCRIPTION Wallet::ACL::Krb5 is the simplest wallet ACL verifier, used to verify ACL -lines of type krb5. The value of such an ACL is a simple Kerberos +lines of type C. The value of such an ACL is a simple Kerberos principal in its text display form, and the ACL grants access to a given principal if and only if the principal exactly matches the ACL. @@ -111,8 +114,8 @@ The PRINCIPAL parameter to check() was undefined or the empty string. Wallet::ACL(3), Wallet::ACL::Base(3), wallet-backend(8) -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/Wallet/ACL/NetDB.pm b/perl/Wallet/ACL/NetDB.pm index 6775c62..2096ba8 100644 --- a/perl/Wallet/ACL/NetDB.pm +++ b/perl/Wallet/ACL/NetDB.pm @@ -1,7 +1,7 @@ # Wallet::ACL::NetDB -- Wallet NetDB role ACL verifier. # # Written by Russ Allbery -# Copyright 2007 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -23,7 +23,7 @@ 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'; +$VERSION = '0.04'; ############################################################################## # Interface @@ -135,6 +135,9 @@ __END__ # Documentation ############################################################################## +=for stopwords +ACL NetDB remctl DNS DHCP Allbery netdb + =head1 NAME Wallet::ACL::NetDB - Wallet ACL verifier for NetDB roles @@ -154,9 +157,10 @@ Wallet::ACL::NetDB - Wallet ACL verifier for NetDB roles =head1 DESCRIPTION Wallet::ACL::NetDB checks a principal against the NetDB roles for a given -host. It is used to verify ACL lines of type netdb. The value of such an -ACL is a node, and the ACL grants access to a given principal if and only -if that principal has one of the roles user, admin, or team for that node. +host. It is used to verify ACL lines of type C. The value of such +an ACL is a node, and the ACL grants access to a given principal if and +only if that principal has one of the roles user, admin, or team for that +node. To use this object, several configuration parameters must be set. See Wallet::Config(3) for details on those configuration parameters and @@ -227,7 +231,7 @@ error message or otherwise returned failure. The ACL parameter to check() was malformed. Currently, this error is only given if ACL is undefined or the empty string. -=item malformed NetDBL remctl token: %s +=item malformed NetDB remctl token: %s The Net::Remctl Perl library returned a malformed token. This should never happen and indicates a bug in Net::Remctl. @@ -248,12 +252,12 @@ grant access is not currently configurable. Net::Remctl(3), Wallet::ACL(3), Wallet::ACL::Base(3), Wallet::Config(3), wallet-backend(8) -NetDB is a free software system for managing DNS, DHCP, and related machine -information for large organizations. For more information on NetDB, see -L. +NetDB is a free software system for managing DNS, DHCP, and related +machine information for large organizations. For more information on +NetDB, see L. -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/Wallet/ACL/NetDB/Root.pm b/perl/Wallet/ACL/NetDB/Root.pm index cbd1387..3aeebda 100644 --- a/perl/Wallet/ACL/NetDB/Root.pm +++ b/perl/Wallet/ACL/NetDB/Root.pm @@ -1,7 +1,7 @@ # Wallet::ACL::NetDB::Root -- Wallet NetDB role ACL verifier (root instances). # # Written by Russ Allbery -# Copyright 2007 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -23,7 +23,7 @@ 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.01'; +$VERSION = '0.02'; ############################################################################## # Interface @@ -48,6 +48,9 @@ sub check { # Documentation ############################################################################## +=for stopwords +ACL NetDB DNS DHCP Allbery + =head1 NAME Wallet::ACL::NetDB::Root - Wallet ACL verifier for NetDB roles (root instances) @@ -66,13 +69,14 @@ Wallet::ACL::NetDB::Root - Wallet ACL verifier for NetDB roles (root instances) =head1 DESCRIPTION -Wallet::ACL::NetDB::Root works identically to Wallet::ACL::NetDB except that -it requires the principal to be a root instance (in other words, to be in -the form /root@) and strips the C portion from the -principal before checking against NetDB roles. As with the base NetDB ACL -verifier, the value of a netdb-root ACL is a node, and the ACL grants access -to a given principal if and only if the that principal (with C -stripped) has one of the roles user, admin, or team for that node. +Wallet::ACL::NetDB::Root works identically to Wallet::ACL::NetDB except +that it requires the principal to be a root instance (in other words, to +be in the form /root@) and strips the C portion +from the principal before checking against NetDB roles. As with the base +NetDB ACL verifier, the value of a C ACL is a node, and the +ACL grants access to a given principal if and only if the that principal +(with C stripped) has one of the roles user, admin, or team for +that node. To use this object, the same configuration parameters must be set as for Wallet::ACL::NetDB. See Wallet::Config(3) for details on those @@ -85,11 +89,11 @@ configuration. =item check(PRINCIPAL, ACL) -Returns true if PRINCIPAL is granted access according to ACL, false if not, -and undef on an error (see L<"DIAGNOSTICS"> below). ACL is a node, and -PRINCIPAL will be granted access if it has an instance of C and if -(with C stripped off and the realm stripped off if configured) has -the user, admin, or team role for that node. +Returns true if PRINCIPAL is granted access according to ACL, false if +not, and undef on an error (see L<"DIAGNOSTICS"> below). ACL is a node, +and PRINCIPAL will be granted access if it has an instance of C and +if (with C stripped off and the realm stripped off if configured) +has the user, admin, or team role for that node. =back @@ -106,15 +110,15 @@ grant access is not currently configurable. =head1 SEE ALSO -Net::Remctl(3), Wallet::ACL(3), Wallet::ACL::Base(3), Wallet::ACL::NetDB(3), -Wallet::Config(3), wallet-backend(8) +Net::Remctl(3), Wallet::ACL(3), Wallet::ACL::Base(3), +Wallet::ACL::NetDB(3), Wallet::Config(3), wallet-backend(8) -NetDB is a free software system for managing DNS, DHCP, and related machine -information for large organizations. For more information on NetDB, see -L. +NetDB is a free software system for managing DNS, DHCP, and related +machine information for large organizations. For more information on +NetDB, see L. -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/Wallet/Admin.pm b/perl/Wallet/Admin.pm index ff87b94..b4b3d86 100644 --- a/perl/Wallet/Admin.pm +++ b/perl/Wallet/Admin.pm @@ -1,7 +1,7 @@ # Wallet::Admin -- Wallet system administrative interface. # # Written by Russ Allbery -# Copyright 2008, 2009 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -413,6 +413,9 @@ __DATA__ Wallet::Admin - Wallet system administrative interface +=for stopwords +ACL hostname ACLs SQL wildcard Allbery + =head1 SYNOPSIS use Wallet::Admin; @@ -429,9 +432,9 @@ thin wrapper around this object that provides a command-line interface to its actions. To use this object, several configuration variables must be set (at least -the database configuration). For information on those variables and how to -set them, see Wallet::Config(3). For more information on the normal user -interface to the wallet server, see Wallet::Server(3). +the database configuration). For information on those variables and how +to set them, see Wallet::Config(3). For more information on the normal +user interface to the wallet server, see Wallet::Server(3). =head1 CLASS METHODS @@ -491,11 +494,11 @@ at least one ACL, but an error can be distinguished from the odd case of a database with no ACLs by calling error(). error() is guaranteed to return the error message if there was an error and undef if there was no error. -There are currently two search types. 'empty' takes no arguments, and will -return only those acls that have no entries within them. 'entry' takes two -arguments -- an entry scheme and an entry identifier -- and will return -any ACLs with an entry that matches the given scheme and contains the -given identifier. +There are currently two search types. C takes no arguments and +will return only those ACLs that have no entries within them. C +takes two arguments, an entry scheme and an entry identifier, and will +return any ACLs with an entry that matches the given scheme and contains +the given identifier. =item list_objects(TYPE, SEARCH) @@ -503,7 +506,7 @@ Returns a list of all objects matching a search type and string in the database, or all objects in the database if no search information is given. The return value is a list of references to pairs of type and name. For example, if two objects existed in the database, both of type -"keytab" and with values "host/example.com" and "foo", list_objects() +C and with values C and C, list_objects() with no arguments would return: ([ 'keytab', 'host/example.com' ], [ 'keytab', 'foo' ]) @@ -513,13 +516,13 @@ database containing no objects, the caller should call error(). error() is guaranteed to return the error message if there was an error and undef if there was no error. -There are four types of searches currently. 'type' (with a given type) +There are four types of searches currently. C (with a given type) will return only those entries where the type matches the given type. -'owner', with a given owner, will only return those objects owned by the -given acl name. 'flag', with a given flag name, will only return those -items with a flag set to the given value. 'acl' operates like 'owner', -but will return only those objects that have the given acl name on any -of the possible acl settings, not just owner. +C, with a given owner, will only return those objects owned by the +given ACL name. C, with a given flag name, will only return those +items with a flag set to the given value. C operates like C, +but will return only those objects that have the given ACL name on any of +the possible ACL settings, not just owner. =item register_object (TYPE, CLASS) @@ -559,8 +562,8 @@ the error message if there was an error and undef if there was no error. wallet-admin(8) -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/Wallet/Config.pm b/perl/Wallet/Config.pm index ae8cf9c..c59d3e3 100644 --- a/perl/Wallet/Config.pm +++ b/perl/Wallet/Config.pm @@ -23,6 +23,11 @@ $PATH = $ENV{WALLET_CONFIG} || '/etc/wallet/wallet.conf'; Wallet::Config - Configuration handling for the wallet server +=for stopwords +DBI DSN SQLite subdirectories KEYTAB keytab kadmind KDC add-ons kadmin DNS +SRV kadmin keytabs remctl backend lowercased NETDB ACL NetDB unscoped +usernames rekey hostnames Allbery wallet-backend keytab-backend + =head1 SYNOPSIS use Wallet::Config; @@ -63,9 +68,9 @@ variable DB_DRIVER to C, use: $DB_DRIVER = 'MySQL'; -Always remember the initial dollar sign (C<$>) and ending semicolon (C<;>). -Those familiar with Perl syntax can of course use the full range of Perl -expressions. +Always remember the initial dollar sign (C<$>) and ending semicolon +(C<;>). Those familiar with Perl syntax can of course use the full range +of Perl expressions. This configuration file should end with the line: @@ -80,11 +85,11 @@ file. =item DB_DRIVER -Sets the Perl database driver to use for the wallet database. Common values -would be C or C. Less common values would be C, -C, or C. The appropriate DBD::* Perl module for the chosen -driver must be installed and will be dynamically loaded by the wallet. For -more information, see DBI(3). +Sets the Perl database driver to use for the wallet database. Common +values would be C or C. Less common values would be +C, C, or C. The appropriate DBD::* Perl module for +the chosen driver must be installed and will be dynamically loaded by the +wallet. For more information, see DBI(3). This variable must be set. @@ -95,8 +100,8 @@ our $DB_DRIVER; =item DB_INFO Sets the remaining contents for the DBI DSN (everything after the driver). -Using this variable provides full control over the connect string passed to -DBI. When using SQLite, set this variable to the path to the SQLite +Using this variable provides full control over the connect string passed +to DBI. When using SQLite, set this variable to the path to the SQLite database. If this variable is set, DB_NAME, DB_HOST, and DB_PORT are ignored. For more information, see DBI(3) and the documentation for the database driver you're using. @@ -111,9 +116,10 @@ our $DB_INFO; =item DB_NAME If DB_INFO is not set, specifies the database name. The third part of the -DBI connect string will be set to C, possibly with a host -and port appended if DB_HOST and DB_PORT are set. For more information, see -DBI(3) and the documentation for the database driver you're using. +DBI connect string will be set to C, possibly with a +host and port appended if DB_HOST and DB_PORT are set. For more +information, see DBI(3) and the documentation for the database driver +you're using. Either DB_INFO or DB_NAME must be set. @@ -124,8 +130,8 @@ our $DB_NAME; =item DB_HOST If DB_INFO is not set, specifies the database host. C<;host=DB_HOST> will -be appended to the DBI connect string. For more information, see DBI(3) and -the documentation for the database driver you're using. +be appended to the DBI connect string. For more information, see DBI(3) +and the documentation for the database driver you're using. =cut @@ -135,8 +141,8 @@ our $DB_HOST; If DB_PORT is not set, specifies the database port. C<;port=DB_PORT> will be appended to the DBI connect string. If this variable is set, DB_HOST -should also be set. For more information, see DBI(3) and the documentation -for the database driver you're using. +should also be set. For more information, see DBI(3) and the +documentation for the database driver you're using. =cut @@ -153,8 +159,8 @@ our $DB_USER; =item DB_PASSWORD -Specifies the password for database authentication. Some database backends, -particularly SQLite, do not need this. +Specifies the password for database authentication. Some database +backends, particularly SQLite, do not need this. =cut @@ -205,9 +211,10 @@ C object type (the Wallet::Object::Keytab class). =item KEYTAB_FILE Specifies the keytab to use to authenticate to B. The principal -whose key is stored in this keytab must have the ability to create, modify, -inspect, and delete any principals that should be managed by the wallet. -(In MIT Kerberos F parlance, this is C privileges.) +whose key is stored in this keytab must have the ability to create, +modify, inspect, and delete any principals that should be managed by the +wallet. (In MIT Kerberos F parlance, this is C +privileges.) KEYTAB_FILE must be set to use keytab objects. @@ -218,12 +225,13 @@ our $KEYTAB_FILE; =item KEYTAB_FLAGS These flags, if any, are passed to the C command when creating a -new principal in the Kerberos KDC. To not pass any flags, set KEYTAB_FLAGS -to the empty string. The default value is C<-clearpolicy>, which clears any -password strength policy from principals created by the wallet. (Since the -wallet randomizes the keys, password strength checking is generally -pointless and may interact poorly with the way C works -when third-party add-ons for password strength checking are used.) +new principal in the Kerberos KDC. To not pass any flags, set +KEYTAB_FLAGS to the empty string. The default value is C<-clearpolicy>, +which clears any password strength policy from principals created by the +wallet. (Since the wallet randomizes the keys, password strength checking +is generally pointless and may interact poorly with the way C works when third-party add-ons for password strength checking +are used.) =cut @@ -264,9 +272,9 @@ our $KEYTAB_KRBTYPE; The principal whose key is stored in KEYTAB_FILE. The wallet will authenticate as this principal to the kadmin service. -KEYTAB_PRINCIPAL must be set to use keytab objects, at least until B -is smart enough to use the first principal found in the keytab it's using -for authentication. +KEYTAB_PRINCIPAL must be set to use keytab objects, at least until +B is smart enough to use the first principal found in the keytab +it's using for authentication. =cut @@ -289,11 +297,11 @@ our $KEYTAB_REALM; =item KEYTAB_TMP A directory into which the wallet can write keytabs temporarily while -processing C commands from clients. The keytabs are written into this -directory with predictable names, so this should not be a system temporary -directory such as F or F. It's best to create a directory -solely for this purpose that's owned by the user the wallet server will run -as. +processing C commands from clients. The keytabs are written into +this directory with predictable names, so this should not be a system +temporary directory such as F or F. It's best to create a +directory solely for this purpose that's owned by the user the wallet +server will run as. KEYTAB_TMP must be set to use keytab objects. @@ -305,20 +313,20 @@ our $KEYTAB_TMP; =head2 Retrieving Existing Keytabs -The keytab object backend optionally supports retrieving existing keys, and -hence keytabs, for Kerberos principals by contacting the KDC via remctl and -talking to B. This is enabled by setting the C -flag on keytab objects. To configure that support, set the following -variables. +The keytab object backend optionally supports retrieving existing keys, +and hence keytabs, for Kerberos principals by contacting the KDC via +remctl and talking to B. This is enabled by setting the +C flag on keytab objects. To configure that support, set the +following variables. =over 4 =item KEYTAB_REMCTL_CACHE -Specifies the ticket cache to use when retrieving existing keytabs from the -KDC. This is only used to implement support for the C flag. -The ticket cache must be for a principal with access to run C via remctl on KEYTAB_REMCTL_HOST. +Specifies the ticket cache to use when retrieving existing keytabs from +the KDC. This is only used to implement support for the C +flag. The ticket cache must be for a principal with access to run +C via remctl on KEYTAB_REMCTL_HOST. =cut @@ -326,10 +334,10 @@ our $KEYTAB_REMCTL_CACHE; =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 flag. This host -must provide the C command and KEYTAB_REMCTL_CACHE must -also be set to a ticket cache for a principal with access to run that +The host to which to connect with remctl to retrieve existing keytabs. +This is only used to implement support for the C flag. This +host must provide the C command and KEYTAB_REMCTL_CACHE +must also be set to a ticket cache for a principal with access to run that command. =cut @@ -339,9 +347,10 @@ 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 flag. -If this variable is not set, the default is formed by prepending C to -KEYTAB_REMCTL_HOST. (Note that KEYTAB_REMCTL_HOST is not lowercased first.) +keytabs. This is only used to implement support for the C +flag. If this variable is not set, the default is formed by prepending +C to KEYTAB_REMCTL_HOST. (Note that KEYTAB_REMCTL_HOST is not +lowercased first.) =cut @@ -365,18 +374,18 @@ our $KEYTAB_REMCTL_PORT; These configuration variables are only needed if you intend to use the C ACL type (the Wallet::ACL::NetDB class). They specify the remctl connection information for retrieving user roles from NetDB and the local -realm to remove from principals (since NetDB normally expects unscoped local -usernames). +realm to remove from principals (since NetDB normally expects unscoped +local usernames). =over 4 =item NETDB_REALM The wallet uses fully-qualified principal names (including the realm), but -NetDB normally expects local usernames without the realm. If this variable -is set, the given realm will be stripped from any principal names before -passing them to NetDB. Principals in other realms will be passed to NetDB -without modification. +NetDB normally expects local usernames without the realm. If this +variable is set, the given realm will be stripped from any principal names +before passing them to NetDB. Principals in other realms will be passed +to NetDB without modification. =cut @@ -385,9 +394,9 @@ our $NETDB_REALM; =item NETDB_REMCTL_CACHE Specifies the ticket cache to use when querying the NetDB remctl interface -for user roles. The ticket cache must be for a principal with access to run -C via remctl on KEYTAB_REMCTL_HOST. This variable must be -set to use NetDB ACLs. +for user roles. The ticket cache must be for a principal with access to +run C via remctl on KEYTAB_REMCTL_HOST. This variable +must be set to use NetDB ACLs. =cut @@ -406,10 +415,10 @@ our $NETDB_REMCTL_HOST; =item NETDB_REMCTL_PRINCIPAL -The service principal to which to authenticate when querying NetDB for user -roles. If this variable is not set, the default is formed by prepending -C to NETDB_REMCTL_HOST. (Note that NETDB_REMCTL_HOST is not -lowercased first.) +The service principal to which to authenticate when querying NetDB for +user roles. If this variable is not set, the default is formed by +prepending C to NETDB_REMCTL_HOST. (Note that NETDB_REMCTL_HOST is +not lowercased first.) =cut @@ -417,9 +426,9 @@ our $NETDB_REMCTL_PRINCIPAL; =item NETDB_REMCTL_PORT -The port on NETDB_REMCTL_HOST to which to connect with remctl to query NetDB -for user roles. If this variable is not set, the default remctl port will -be used. +The port on NETDB_REMCTL_HOST to which to connect with remctl to query +NetDB for user roles. If this variable is not set, the default remctl +port will be used. =cut @@ -430,17 +439,18 @@ our $NETDB_REMCTL_PORT; =head1 DEFAULT OWNERS By default, only users in the ADMIN ACL can create new objects in the -wallet. To allow other users to create new objects, define a Perl function -named default_owner. This function will be called whenever a non-ADMIN user -tries to create a new object and will be passed the type and name of the -object. It should return undef if there is no default owner for that -object. If there is, it should return a list containing the name to use for -the ACL and then zero or more anonymous arrays of two elements each giving -the type and identifier for each ACL entry. - -For example, the following simple function says to use a default owner named -C with one entry of type C and identifier C -for the object with type C and name C: +wallet. To allow other users to create new objects, define a Perl +function named default_owner. This function will be called whenever a +non-ADMIN user tries to create a new object and will be passed the type +and name of the object. It should return undef if there is no default +owner for that object. If there is, it should return a list containing +the name to use for the ACL and then zero or more anonymous arrays of two +elements each giving the type and identifier for each ACL entry. + +For example, the following simple function says to use a default owner +named C with one entry of type C and identifier +C for the object with type C and name +C: sub default_owner { my ($type, $name) = @_; @@ -453,8 +463,8 @@ for the object with type C and name C: Of course, normally this function is used for more complex mappings. Here is a more complete example. For objects of type keytab corresponding to -various types of per-machine principals, return a default owner that sets as -owner anyone with a NetDB role for that system and the system's host +various types of per-machine principals, return a default owner that sets +as owner anyone with a NetDB role for that system and the system's host principal. This permits authorization management using NetDB while also allowing the system to bootstrap itself once the host principal has been downloaded and rekey itself using the old host principal. @@ -474,17 +484,19 @@ downloaded and rekey itself using the old host principal. return ($acl_name, @acl); } -The auto-created ACL used for the owner of the new object will, in the above -example, be named C> where I is the fully-qualified -name of the system as derived from the keytab being requested. - -If the name of the ACL returned by the default_owner function matches an ACL -that already exists in the wallet database, the existing ACL will be -compared to the default ACL returned by the default_owner function. If the -existing ACL has the same entries as the one returned by default_owner, -creation continues if the user is authorized by that ACL. If they don't -match, creation of the object is rejected, since the presence of an existing -ACL may indicate that something different is being done with this object. +The auto-created ACL used for the owner of the new object will, in the +above example, be named C> where I is the +fully-qualified name of the system as derived from the keytab being +requested. + +If the name of the ACL returned by the default_owner function matches an +ACL that already exists in the wallet database, the existing ACL will be +compared to the default ACL returned by the default_owner function. If +the existing ACL has the same entries as the one returned by +default_owner, creation continues if the user is authorized by that ACL. +If they don't match, creation of the object is rejected, since the +presence of an existing ACL may indicate that something different is being +done with this object. =head1 NAMING ENFORCEMENT diff --git a/perl/Wallet/Database.pm b/perl/Wallet/Database.pm index 68fb6bb..7b3474a 100644 --- a/perl/Wallet/Database.pm +++ b/perl/Wallet/Database.pm @@ -6,7 +6,7 @@ # like DBI objects in the rest of the code. # # Written by Russ Allbery -# Copyright 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -39,7 +39,7 @@ 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.01'; +$VERSION = '0.02'; ############################################################################## # Core overrides @@ -84,6 +84,9 @@ __END__ Wallet::Dabase - Wrapper module for wallet database connections +=for stopwords +DBI RaiseError PrintError AutoCommit Allbery + =head1 SYNOPSIS use Wallet::Database; @@ -93,9 +96,9 @@ Wallet::Dabase - Wrapper module for wallet database connections Wallet::Database is a thin wrapper module around DBI that takes care of building a connect string and setting database options based on wallet -configuration. The only overriden method is connect(). All other methods -should work the same as in DBI and Wallet::Database objects should be -usable exactly as if they were DBI objects. +configuration. The only overridden method is connect(). All other +methods should work the same as in DBI and Wallet::Database objects should +be usable exactly as if they were DBI objects. connect() will obtain the database connection information from the wallet configuration; see Wallet::Config(3) for more details. It will also @@ -120,8 +123,8 @@ configuration. DBI(3), Wallet::Config(3) -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 65ddf4b..b653f87 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -55,6 +55,9 @@ __END__ # Documentation ############################################################################## +=for stopwords +Kadmin keytabs keytab Heimdal API kadmind kadmin + =head1 NAME Wallet::Kadmin - Kadmin module wrapper for wallet keytabs @@ -69,21 +72,21 @@ Wallet::Kadmin - Kadmin module wrapper for wallet keytabs =head1 DESCRIPTION -Wallet::Kadmin is a wrapper to modules that provide an interface for keytab -integration with the wallet. Each module is meant to interface with a -specific type of Kerberos implementation, such as MIT Kerberos or Heimdal -Kerberos, and provide a standndard set of API calls used to interact with -that implementation's kadmind. +Wallet::Kadmin is a wrapper to modules that provide an interface for +keytab integration with wallet. Each module is meant to interface with a +specific type of Kerberos implementation, such as MIT Kerberos or Heimdal, +and provide a standard set of API calls used to interact with that +implementation's kadmin interface. The class simply uses Wallet::Config to find which type of kadmind we have requested to use, and then returns an object to use for interacting with that kadmind. 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 be created in Kerberos and then a keytab is -generated and stored in a file on disk. +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 be created in Kerberos and then a +keytab is generated and stored in a file on disk. To use this object, several configuration parameters must be set. See Wallet::Config(3) for details on those configuration parameters and @@ -95,9 +98,9 @@ information about how to set wallet configuration. =item new() -Finds the proper Kerberos implementation and calls the new() constructor for -that implementation's module, returning the result. If the implementation -is not recognized or set, die with an error message. +Finds the proper Kerberos implementation and calls the new() constructor +for that implementation's module, returning the result. If the +implementation is not recognized or set, die with an error message. =back @@ -105,8 +108,8 @@ is not recognized or set, die with an error message. 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. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHORS diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index 428202b..2ad35e3 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -230,9 +230,12 @@ __END__ # Documentation ############################################################################## +=for stopwords +keytabs keytab kadmin enctypes API ENCTYPES enctype Allbery Heimdal + =head1 NAME -Wallet::Kadmin::MIT - MIT admin interactions for wallet keytabs +Wallet::Kadmin::Heimdal - Heimdal admin interactions for wallet keytabs =head1 SYNOPSIS @@ -244,18 +247,18 @@ Wallet::Kadmin::MIT - MIT admin interactions for wallet keytabs =head1 DESCRIPTION -Wallet::Kadmin::MIT is an interface for keytab integration with the wallet, -specifically for using kadmin to create, delete, and add enctypes to keytabs. -It implments the wallet kadmin API and provides the necessary glue to MIT -Kerberos installs for each of these functions, while allowing the wallet -to keep the details of what type of Kerberos installation is being used -abstracted. +Wallet::Kadmin::Heimdal is an interface for keytab integration with the +wallet, specifically for using kadmin to create, delete, and add enctypes +to keytabs. It implements the wallet kadmin API and provides the +necessary glue to Heimdal installs for each of these functions, while +allowing the wallet to keep the details of what type of Kerberos +installation is being used abstracted. 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 be created in Kerberos and then a keytab is -generated and stored in a file on disk. +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 be created in Kerberos and then a +keytab is generated and stored in a file on disk. To use this object, several configuration parameters must be set. See Wallet::Config(3) for details on those configuration parameters and @@ -268,17 +271,17 @@ information about how to set wallet configuration. =item addprinc(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, or throws an error if there was a failure in adding the principal. -If the principal already exists, return true as we are bringing our -expectations in line with reality. +random password, and any other flags set by Wallet::Config. Returns true +on success, or throws an error if there was a failure in adding the +principal. If the principal already exists, return true as we are +bringing our expectations in line with reality. =item addprinc(PRINCIPAL) -Removes a principal with the given name. Returns true on success, or throws -an error if there was a failure in removing the principal. If the principal -does not exist, return true as we are bringing our expectations in line with -reality. +Removes a principal with the given name. Returns true on success, or +throws an error if there was a failure in removing the principal. If the +principal does not exist, return true as we are bringing our expectations +in line with reality. =item ktadd(PRINCIPAL, FILE, ENCTYPES) @@ -290,19 +293,12 @@ otherwise true is returned. =back -=head1 LIMITATIONS - -Currently, this implementation calls an external B program rather - than using a native Perl module and therefore requires B be -installed and parses its output. It may miss some error conditions if the -output of B ever changes. - =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. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHORS diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index 49691b0..8449868 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -226,6 +226,9 @@ __END__ # Documentation ############################################################################## +=for stopwords +keytabs keytab kadmin enctype enctypes API ENCTYPES Allbery + =head1 NAME Wallet::Kadmin::MIT - MIT admin interactions for wallet keytabs @@ -240,18 +243,18 @@ Wallet::Kadmin::MIT - MIT admin interactions for wallet keytabs =head1 DESCRIPTION -Wallet::Kadmin::MIT is an interface for keytab integration with the wallet, -specifically for using kadmin to create, delete, and add enctypes to keytabs. -It implments the wallet kadmin API and provides the necessary glue to MIT -Kerberos installs for each of these functions, while allowing the wallet -to keep the details of what type of Kerberos installation is being used -abstracted. +Wallet::Kadmin::MIT is an interface for keytab integration with the +wallet, specifically for using kadmin to create, delete, and add enctypes +to keytabs. It implements the wallet kadmin API and provides the +necessary glue to MIT Kerberos installs for each of these functions, while +allowing the wallet to keep the details of what type of Kerberos +installation is being used abstracted. 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 be created in Kerberos and then a keytab is -generated and stored in a file on disk. +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 be created in Kerberos and then a +keytab is generated and stored in a file on disk. To use this object, several configuration parameters must be set. See Wallet::Config(3) for details on those configuration parameters and @@ -264,17 +267,17 @@ information about how to set wallet configuration. =item addprinc(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, or throws an error if there was a failure in adding the principal. -If the principal already exists, return true as we are bringing our -expectations in line with reality. +random password, and any other flags set by Wallet::Config. Returns true +on success, or throws an error if there was a failure in adding the +principal. If the principal already exists, return true as we are +bringing our expectations in line with reality. -=item addprinc(PRINCIPAL) +=item delprinc(PRINCIPAL) -Removes a principal with the given name. Returns true on success, or throws -an error if there was a failure in removing the principal. If the principal -does not exist, return true as we are bringing our expectations in line with -reality. +Removes a principal with the given name. Returns true on success, or +throws an error if there was a failure in removing the principal. If the +principal does not exist, return true as we are bringing our expectations +in line with reality. =item ktadd(PRINCIPAL, FILE, ENCTYPES) @@ -297,8 +300,8 @@ output of B ever changes. 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. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHORS diff --git a/perl/Wallet/Object/Base.pm b/perl/Wallet/Object/Base.pm index fea0320..5097729 100644 --- a/perl/Wallet/Object/Base.pm +++ b/perl/Wallet/Object/Base.pm @@ -1,7 +1,7 @@ # Wallet::Object::Base -- Parent class for any object stored in the wallet. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -22,7 +22,7 @@ use Wallet::ACL; # 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.04'; +$VERSION = '0.05'; ############################################################################## # Constructors @@ -669,6 +669,10 @@ __END__ Wallet::Object::Base - Generic parent class for wallet objects +=for stopwords +DBH HOSTNAME DATETIME ACL backend metadata timestamp Allbery wallet-backend +backend-specific + =head1 SYNOPSIS package Wallet::Object::Simple; @@ -682,104 +686,107 @@ Wallet::Object::Base - Generic parent class for wallet objects =head1 DESCRIPTION Wallet::Object::Base is the generic parent class for wallet objects (data -types that can be stored in the wallet system). It provides defualt +types that can be stored in the wallet system). It provides default functions and behavior, including handling generic object settings. All handlers for objects stored in the wallet should inherit from it. It is not used directly. =head1 PUBLIC CLASS METHODS -The following methods are called by the rest of the wallet system and should -be implemented by all objects stored in the wallet. They should be called -with the desired wallet object class as the first argument (generally using -the Wallet::Object::Type->new syntax). +The following methods are called by the rest of the wallet system and +should be implemented by all objects stored in the wallet. They should be +called with the desired wallet object class as the first argument +(generally using the Wallet::Object::Type->new syntax). =over 4 =item new(TYPE, NAME, DBH) Creates a new object with the given object type and name, based on data -already in the database. This method will only succeed if an object of the -given TYPE and NAME is already present in the wallet database. If no such -object exits, throws an exception. Otherwise, returns an object blessed -into the class used for the new() call (so subclasses can leave this method -alone and not override it). +already in the database. This method will only succeed if an object of +the given TYPE and NAME is already present in the wallet database. If no +such object exits, throws an exception. Otherwise, returns an object +blessed into the class used for the new() call (so subclasses can leave +this method alone and not override it). -Takes a Wallet::Database object, which is stored in the object and used for -any further operations. +Takes a Wallet::Database object, which is stored in the object and used +for any further operations. =item create(TYPE, NAME, DBH, PRINCIPAL, HOSTNAME [, DATETIME]) Similar to new() but instead creates a new entry in the database. This method will throw an exception if an entry for that type and name already -exists in the database or if creating the database record fails. Otherwise, -a new database entry will be created with that type and name, no owner, no -ACLs, no expiration, no flags, and with created by, from, and on set to the -PRINCIPAL, HOSTNAME, and DATETIME parameters. If DATETIME isn't given, the -current time is used. The database handle is treated as with new(). +exists in the database or if creating the database record fails. +Otherwise, a new database entry will be created with that type and name, +no owner, no ACLs, no expiration, no flags, and with created by, from, and +on set to the PRINCIPAL, HOSTNAME, and DATETIME parameters. If DATETIME +isn't given, the current time is used. The database handle is treated as +with new(). =back =head1 PUBLIC INSTANCE METHODS The following methods may be called on instantiated wallet objects. -Normally, the only methods that a subclass will need to override are get(), -store(), show(), and destroy(). +Normally, the only methods that a subclass will need to override are +get(), store(), show(), and destroy(). -If the locked flag is set on an object, no actions may be performed on that -object except for the flag methods and show(). All other actions will be -rejected with an error saying the object is locked. +If the locked flag is set on an object, no actions may be performed on +that object except for the flag methods and show(). All other actions +will be rejected with an error saying the object is locked. =over 4 =item acl(TYPE [, ACL, PRINCIPAL, HOSTNAME [, DATETIME]]) -Sets or retrieves a given object ACL as a numeric ACL ID. TYPE must be one -of C, C, C, C, or C, corresponding to the -ACLs kept on an object. If no other arguments are given, returns the -current ACL setting as an ACL ID or undef if that ACL isn't set. If other -arguments are given, change that ACL to ACL and return true on success and -false on failure. Pass in the empty string for ACL to clear the ACL. The -other arguments are used for logging and history and should indicate the -user and host from which the change is made and the time of the change. +Sets or retrieves a given object ACL as a numeric ACL ID. TYPE must be +one of C, C, C, C, or C, corresponding +to the ACLs kept on an object. If no other arguments are given, returns +the current ACL setting as an ACL ID or undef if that ACL isn't set. If +other arguments are given, change that ACL to ACL and return true on +success and false on failure. Pass in the empty string for ACL to clear +the ACL. The other arguments are used for logging and history and should +indicate the user and host from which the change is made and the time of +the change. =item attr(ATTRIBUTE [, VALUES, PRINCIPAL, HOSTNAME [, DATETIME]]) Sets or retrieves a given object attribute. Attributes are used to store -backend-specific information for a particular object type and ATTRIBUTE must -be an attribute type known to the underlying object implementation. The -default implementation of this method rejects all attributes as unknown. +backend-specific information for a particular object type and ATTRIBUTE +must be an attribute type known to the underlying object implementation. +The default implementation of this method rejects all attributes as +unknown. If no other arguments besides ATTRIBUTE are given, returns the values of that attribute, if any, as a list. On error, returns the empty list. To -distinguish between an error and an empty return, call error() afterwards. +distinguish between an error and an empty return, call error() afterward. It is guaranteed to return undef unless there was an error. If other arguments are given, sets the given ATTRIBUTE values to VALUES, -which must be a reference to an array (even if only one value is being set). -Pass a reference to an empty array to clear the attribute values. The other -arguments are used for logging and history and should indicate the user and -host from which the change is made and the time of the change. Returns true -on success and false on failure. +which must be a reference to an array (even if only one value is being +set). Pass a reference to an empty array to clear the attribute values. +The other arguments are used for logging and history and should indicate +the user and host from which the change is made and the time of the +change. Returns true on success and false on failure. =item attr_show() -Returns a formatted text description of the type-specific attributes of the -object, or undef on error. The default implementation of this method always -returns the empty string. If there are any type-specific attributes set, -this method should return that metadata, formatted as key: value pairs with -the keys right-aligned in the first 15 characters, followed by a space, a -colon, and the value. +Returns a formatted text description of the type-specific attributes of +the object, or undef on error. The default implementation of this method +always returns the empty string. If there are any type-specific +attributes set, this method should return that metadata, formatted as key: +value pairs with the keys right-aligned in the first 15 characters, +followed by a space, a colon, and the value. =item destroy(PRINCIPAL, HOSTNAME [, DATETIME]) Destroys the object by removing all record of it from the database. The -Wallet::Object::Base implementation handles the generic database work, -but any subclass should override this method to do any deletion of files -or entries in external databases and any other database entries and then -call the parent method to handle the generic database cleanup. Returns -true on success and false on failure. The arguments are used for logging -and history and should indicate the user and host from which the change is +Wallet::Object::Base implementation handles the generic database work, but +any subclass should override this method to do any deletion of files or +entries in external databases and any other database entries and then call +the parent method to handle the generic database cleanup. Returns true on +success and false on failure. The arguments are used for logging and +history and should indicate the user and host from which the change is made and the time of the change. =item error([ERROR ...]) @@ -789,47 +796,50 @@ 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> 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. +one or more error strings. If so, those strings are concatenated +together, trailing newlines are removed, any text of the form S> 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 expires([EXPIRES, PRINCIPAL, HOSTNAME [, DATETIME]]) Sets or retrieves the expiration date of an object. If no arguments are -given, returns the current expiration or undef if no expiration is set. If -arguments are given, change the expiration to EXPIRES and return true on -success and false on failure. EXPIRES must be in the format C, although the time portion may be omitted. Pass in the empty -string for EXPIRES to clear the expiration date. - -The other arguments are used for logging and history and should indicate the -user and host from which the change is made and the time of the change. +given, returns the current expiration or undef if no expiration is set. +If arguments are given, change the expiration to EXPIRES and return true +on success and false on failure. EXPIRES must be in the format +C, although the time portion may be omitted. Pass in +the empty string for EXPIRES to clear the expiration date. + +The other arguments are used for logging and history and should indicate +the user and host from which the change is made and the time of the +change. =item flag_check(FLAG) -Check whether the given flag is set on an object. Returns true if set, C<0> -if not set, and undef on error. +Check whether the given flag is set on an object. Returns true if set, +C<0> if not set, and undef on error. =item flag_clear(FLAG, PRINCIPAL, HOSTNAME [, DATETIME]) Clears FLAG on an object. Returns true on success and false on failure. -The other arguments are used for logging and history and should indicate the -user and host from which the change is made and the time of the change. +The other arguments are used for logging and history and should indicate +the user and host from which the change is made and the time of the +change. =item flag_list() List the flags set on an object. If no flags are set, returns the empty -list. On failure, returns an empty list. To distinguish between the empty -response and an error, the caller should call error() after an empty return. -It is guaranteed to return undef if there was no error. +list. On failure, returns an empty list. To distinguish between the +empty response and an error, the caller should call error() after an empty +return. It is guaranteed to return undef if there was no error. =item flag_set(FLAG, PRINCIPAL, HOSTNAME [, DATETIME]) Sets FLAG on an object. Returns true on success and false on failure. -The other arguments are used for logging and history and should indicate the -user and host from which the change is made and the time of the change. +The other arguments are used for logging and history and should indicate +the user and host from which the change is made and the time of the +change. =item get(PRINCIPAL, HOSTNAME [, DATETIME]) @@ -856,9 +866,9 @@ Sets or retrieves the owner of an object as a numeric ACL ID. If no arguments are given, returns the current owner ACL ID or undef if none is set. If arguments are given, change the owner to OWNER and return true on success and false on failure. Pass in the empty string for OWNER to clear -the owner. The other arguments are used for logging and history and should -indicate the user and host from which the change is made and the time of the -change. +the owner. The other arguments are used for logging and history and +should indicate the user and host from which the change is made and the +time of the change. =item show() @@ -866,17 +876,17 @@ Returns a formatted text description of the object suitable for human display, or undef on error. All of the base metadata about the object, formatted as key: value pairs with the keys aligned in the first 15 characters followed by a space, a colon, and the value. The attr_show() -method of the object is also called and any formatted output it returns will -be included. If any ACLs or an owner are set, after this data there is a -blank line and then the information for each unique ACL, separated by blank -lines. +method of the object is also called and any formatted output it returns +will be included. If any ACLs or an owner are set, after this data there +is a blank line and then the information for each unique ACL, separated by +blank lines. =item store(DATA, PRINCIPAL, HOSTNAME [, DATETIME]) Store user-supplied data into the given object. This may not be supported -by all backends (for instance, backends that automatically generate the data -will not support this). The default implementation rejects all store() -calls with an error message saying that the object is immutable. +by all backends (for instance, backends that automatically generate the +data will not support this). The default implementation rejects all +store() calls with an error message saying that the object is immutable. =item type() @@ -894,23 +904,24 @@ provided for subclasses to call to implement some generic actions. =item log_action (ACTION, PRINCIPAL, HOSTNAME, DATETIME) Updates the history tables and trace information appropriately for ACTION, -which should be either C or C. No other changes are made to the -database, just updates of the history table and trace fields with the +which should be either C or C. No other changes are made to +the database, just updates of the history table and trace fields with the provided data about who performed the action and when. -This function commits its transaction when complete and therefore should not -be called inside another transaction. Normally it's called as a separate -transaction after the data is successfully stored or retrieved. +This function commits its transaction when complete and therefore should +not be called inside another transaction. Normally it's called as a +separate transaction after the data is successfully stored or retrieved. =item log_set (FIELD, OLD, NEW, PRINCIPAL, HOSTNAME, DATETIME) -Updates the history tables for the change in a setting value for an object. -FIELD should be one of C, C, C, C, -C, C, C, C, or a value starting with -C followed by a space and a type-specific field name. The last -form is the most common form used by a subclass. OLD is the previous value -of the field or undef if the field was unset, and NEW is the new value of -the field or undef if the field should be unset. +Updates the history tables for the change in a setting value for an +object. FIELD should be one of C, C, C, +C, C, C, C, C, or a +value starting with C followed by a space and a type-specific +field name. The last form is the most common form used by a subclass. +OLD is the previous value of the field or undef if the field was unset, +and NEW is the new value of the field or undef if the field should be +unset. This function does not commit and does not catch database exceptions. It should normally be called as part of a larger transaction that implements @@ -922,8 +933,8 @@ the change in the setting. wallet-backend(8) -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/Wallet/Object/File.pm b/perl/Wallet/Object/File.pm index be72d7f..69262f6 100644 --- a/perl/Wallet/Object/File.pm +++ b/perl/Wallet/Object/File.pm @@ -1,7 +1,7 @@ # Wallet::Object::File -- File object implementation for the wallet. # # Written by Russ Allbery -# Copyright 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -24,7 +24,7 @@ use Wallet::Object::Base; # 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.01'; +$VERSION = '0.02'; ############################################################################## # File naming @@ -136,6 +136,9 @@ __END__ Wallet::Object::File - File object implementation for wallet +=for stopwords +API HOSTNAME DATETIME keytab remctld backend nul Allbery wallet-backend + =head1 SYNOPSIS my @name = qw(file mysql-lsdb) @@ -163,17 +166,18 @@ set wallet configuration. =head1 METHODS This object mostly inherits from Wallet::Object::Base. See the -documentation for that class for all generic methods. Below are only those -methods that are overridden or behave specially for this implementation. +documentation for that class for all generic methods. Below are only +those methods that are overridden or behave specially for this +implementation. =over 4 =item destroy(PRINCIPAL, HOSTNAME [, DATETIME]) Destroys a file object by removing it from the database and deleting the -corresonding file on the wallet server. Returns true on success and false -on failure. The caller should call error() to get the error message after -a failure. PRINCIPAL, HOSTNAME, and DATETIME are stored as history +corresponding file on the wallet server. Returns true on success and +false on failure. The caller should call error() to get the error message +after a failure. PRINCIPAL, HOSTNAME, and DATETIME are stored as history information. PRINCIPAL should be the user who is destroying the object. If DATETIME isn't given, the current time is used. diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index b604907..760280f 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -382,6 +382,10 @@ __END__ # Documentation ############################################################################## +=for stopwords +keytab API KDC keytabs HOSTNAME DATETIME enctypes enctype DBH metadata +unmanaged kadmin Allbery + =head1 NAME Wallet::Object::Keytab - Keytab object implementation for wallet @@ -396,17 +400,17 @@ Wallet::Object::Keytab - Keytab object implementation for wallet =head1 DESCRIPTION -Wallet::Object::Keytab is a representation of Kerberos keytab objects in the -wallet. It implements the wallet object API and provides the necessary -glue to create principals in a Kerberos KDC, create and return keytabs for -those principals, and delete them out of Kerberos when the wallet object is -destroyed. +Wallet::Object::Keytab is a representation of Kerberos keytab objects in +the wallet. It implements the wallet object API and provides the +necessary glue to create principals in a Kerberos KDC, create and return +keytabs for those principals, and delete them out of Kerberos when the +wallet object is destroyed. 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 be created in Kerberos and then a keytab is -generated and stored in a file on disk. +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 be created in Kerberos and then a +keytab is generated and stored in a file on disk. This implementation generates a new random key (and hence invalidates all existing keytabs) each time the keytab is retrieved with the get() method. @@ -418,8 +422,9 @@ information about how to set wallet configuration. =head1 METHODS This object mostly inherits from Wallet::Object::Base. See the -documentation for that class for all generic methods. Below are only those -methods that are overridden or behave specially for this implementation. +documentation for that class for all generic methods. Below are only +those methods that are overridden or behave specially for this +implementation. =over 4 @@ -453,12 +458,12 @@ enctypes than those requested by this attribute. If no other arguments besides ATTRIBUTE are given, returns the values of that attribute, if any, as a list. On error, returns the empty list. To -distinguish between an error and an empty return, call error() afterwards. +distinguish between an error and an empty return, call error() afterward. It is guaranteed to return undef unless there was an error. If other arguments are given, sets the given ATTRIBUTE values to VALUES, -which must be a reference to an array (even if only one value is being set). -Pass a reference to an empty array to clear the attribute values. +which must be a reference to an array (even if only one value is being +set). Pass a reference to an empty array to clear the attribute values. PRINCIPAL, HOSTNAME, and DATETIME are stored as history information. PRINCIPAL should be the user who is destroying the object. If DATETIME isn't given, the current time is used. @@ -467,12 +472,12 @@ isn't given, the current time is used. This is a class method and should be called on the Wallet::Object::Keytab class. It creates a new object with the given TYPE and NAME (TYPE is -normally C and must be for the rest of the wallet system to use the -right class, but this module doesn't check for ease of subclassing), using -DBH as the handle to the wallet metadata database. PRINCIPAL, HOSTNAME, and -DATETIME are stored as history information. PRINCIPAL should be the user -who is creating the object. If DATETIME isn't given, the current time is -used. +normally C and must be for the rest of the wallet system to use +the right class, but this module doesn't check for ease of subclassing), +using DBH as the handle to the wallet metadata database. PRINCIPAL, +HOSTNAME, and DATETIME are stored as history information. PRINCIPAL +should be the user who is creating the object. If DATETIME isn't given, +the current time is used. When a new keytab object is created, the Kerberos principal designated by NAME is also created in the Kerberos realm determined from the wallet @@ -515,9 +520,9 @@ used. =item KEYTAB_TMP/keytab. -The keytab is created in this file using C and then read into memory. -KEYTAB_TMP is set in the wallet configuration, and is the process ID -of the current process. The file is unlinked after being read. +The keytab is created in this file using C and then read into +memory. KEYTAB_TMP is set in the wallet configuration, and is the +process ID of the current process. The file is unlinked after being read. =back @@ -536,8 +541,8 @@ wallet database do not have realm information. kadmin(8), Wallet::Config(3), Wallet::Object::Base(3), wallet-backend(8) -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/Wallet/Schema.pm b/perl/Wallet/Schema.pm index 252da03..589a15d 100644 --- a/perl/Wallet/Schema.pm +++ b/perl/Wallet/Schema.pm @@ -133,6 +133,10 @@ __DATA__ Wallet::Schema - Database schema for the wallet system +=for stopwords +SQL ACL API APIs enums Enums Keytab Backend keytab backend enctypes +enctype Allbery + =head1 SYNOPSIS use Wallet::Schema; @@ -157,30 +161,30 @@ MySQL and may require some modifications for other databases. =item new() -Instantiates a new Wallet::Schema object. This parses the documentation and -extracts the schema, but otherwise doesn't do anything. +Instantiates a new Wallet::Schema object. This parses the documentation +and extracts the schema, but otherwise doesn't do anything. =item create(DBH) -Given a connected database handle, runs the SQL commands necessary to create -the wallet database in an otherwise empty database. This method will not -drop any existing tables and will therefore fail if a wallet database has -already been created. On any error, this method will throw a database -exception. +Given a connected database handle, runs the SQL commands necessary to +create the wallet database in an otherwise empty database. This method +will not drop any existing tables and will therefore fail if a wallet +database has already been created. On any error, this method will throw a +database exception. =item drop(DBH) Given a connected database handle, drop all of the wallet tables from that -database if any of those tables exist. This method will only remove tables -that are part of the current schema or one of the previous known schema and -won't remove other tables. On any error, this method will throw a database -exception. +database if any of those tables exist. This method will only remove +tables that are part of the current schema or one of the previous known +schema and won't remove other tables. On any error, this method will +throw a database exception. =item sql() -Returns the schema and the population of the normalization tables as a list -of SQL commands to run to create the wallet database in an otherwise empty -database. +Returns the schema and the population of the normalization tables as a +list of SQL commands to run to create the wallet database in an otherwise +empty database. =back @@ -188,8 +192,8 @@ database. =head2 Normalization Tables -The following are normalization tables used to constrain the values in other -tables. +The following are normalization tables used to constrain the values in +other tables. Holds the supported flag names: @@ -221,16 +225,16 @@ Holds the supported ACL schemes and their corresponding Perl classes: values ('netdb-root', 'Wallet::ACL::NetDB::Root'); If you have extended the wallet to support additional object types or -additional ACL schemes, you will want to add additional rows to these tables -mapping those types or schemes to Perl classes that implement the object or -ACL verifier APIs. +additional ACL schemes, you will want to add additional rows to these +tables mapping those types or schemes to Perl classes that implement the +object or ACL verifier APIs. =head2 ACL Tables -A wallet ACL consists of zero or more ACL entries, each of which is a scheme -and an identifier. The scheme identifies the check that should be performed -and the identifier is additional scheme-specific information. Each ACL -references entries in the following table: +A wallet ACL consists of zero or more ACL entries, each of which is a +scheme and an identifier. The scheme identifies the check that should be +performed and the identifier is additional scheme-specific information. +Each ACL references entries in the following table: create table acls (ac_id integer auto_increment primary key, @@ -249,8 +253,9 @@ in: create index ae_id on acl_entries (ae_id); ACLs may be referred to in the API via either the numeric ID or the -human-readable name, but internally ACLs are always referenced by numeric ID -so that they can be renamed without requiring complex data modifications. +human-readable name, but internally ACLs are always referenced by numeric +ID so that they can be renamed without requiring complex data +modifications. Currently, the ACL named C (case-sensitive) is special-cased in the Wallet::Server code and granted global access. @@ -269,17 +274,18 @@ table. ah_on datetime not null); create index ah_acl on acl_history (ah_acl); -ah_action must be one of C, C, C, or C (enums -aren't used for compatibility with databases other than MySQL). For a -change of type create or destroy, only the action and the trace records (by, -from, and on) are stored. For a change to the lines of an ACL, the scheme -and identifier of the line that was added or removed is included. Note that -changes to the ACL name are not recorded; ACLs are always tracked by -system-generated ID, so name changes are purely cosmetic. +ah_action must be one of C, C, C, or C +(enums aren't used for compatibility with databases other than MySQL). +For a change of type create or destroy, only the action and the trace +records (by, from, and on) are stored. For a change to the lines of an +ACL, the scheme and identifier of the line that was added or removed is +included. Note that changes to the ACL name are not recorded; ACLs are +always tracked by system-generated ID, so name changes are purely +cosmetic. -ah_by stores the authenticated identity that made the change, ah_from stores -the host from which they made the change, and ah_on stores the time the -change was made. +ah_by stores the authenticated identity that made the change, ah_from +stores the host from which they made the change, and ah_on stores the time +the change was made. =head2 Object Tables @@ -311,13 +317,13 @@ table: create index ob_expires on objects (ob_expires); Object names are not globally unique but only unique within their type, so -the table has a joint primary key. Each object has an owner and then up to -five more specific ACLs. The owner provides permission for get, store, and -show operations if no more specific ACL is set. It does not provide +the table has a joint primary key. Each object has an owner and then up +to five more specific ACLs. The owner provides permission for get, store, +and show operations if no more specific ACL is set. It does not provide permission for destroy or flags. -The ob_acl_flags ACL controls who can set flags on this object. Each object -may have zero or more flags associated with it: +The ob_acl_flags ACL controls who can set flags on this object. Each +object may have zero or more flags associated with it: create table flags (fl_type varchar(16) @@ -348,27 +354,28 @@ this table: oh_on datetime not null); create index oh_object on object_history (oh_type, oh_name); -oh_action must be one of C, C, C, C, or C. -oh_field must be one of C, C, C, C, -C, C, C, C, or C. Enums -aren't used for compatibility with databases other than MySQL. - -For a change of type create, get, store, or destroy, only the action and the -trace records (by, from, and on) are stored. For changes to columns or to -the flags table, oh_field takes what attribute is changed, oh_from takes the -previous value converted to a string and oh_to takes the next value -similarly converted to a string. The special field value "type_data" is -used when type-specific data is changed, and in that case (and only that -case) some type-specific name for the data being changed is stored in -oh_type_field. +oh_action must be one of C, C, C, C, or +C. oh_field must be one of C, C, C, +C, C, C, C, C, or +C. Enums aren't used for compatibility with databases other +than MySQL. + +For a change of type create, get, store, or destroy, only the action and +the trace records (by, from, and on) are stored. For changes to columns +or to the flags table, oh_field takes what attribute is changed, oh_from +takes the previous value converted to a string and oh_to takes the next +value similarly converted to a string. The special field value +"type_data" is used when type-specific data is changed, and in that case +(and only that case) some type-specific name for the data being changed is +stored in oh_type_field. When clearing a flag, oh_old will have the name of the flag and oh_new will be null. When setting a flag, oh_old will be null and oh_new will have the name of the flag. -oh_by stores the authenticated identity that made the change, oh_from stores -the host from which they made the change, and oh_on stores the time the -change was made. +oh_by stores the authenticated identity that made the change, oh_from +stores the host from which they made the change, and oh_on stores the time +the change was made. =head2 Keytab Backend Data @@ -406,16 +413,16 @@ and then the restrictions for a given keytab are stored in this table: primary key (ke_name, ke_enctype)); create index ke_name on keytab_enctypes (ke_name); -To use this functionality, you will need to populate the enctypes table with -the enctypes that a keytab may be restricted to. Currently, there is no -automated mechanism to do this. +To use this functionality, you will need to populate the enctypes table +with the enctypes that a keytab may be restricted to. Currently, there is +no automated mechanism to do this. =head1 SEE ALSO wallet-backend(8) -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/Wallet/Server.pm b/perl/Wallet/Server.pm index 40e48a3..dd596c4 100644 --- a/perl/Wallet/Server.pm +++ b/perl/Wallet/Server.pm @@ -1,7 +1,7 @@ # Wallet::Server -- Wallet system server implementation. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -23,7 +23,7 @@ use Wallet::Schema; # 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.07'; +$VERSION = '0.08'; ############################################################################## # Utility methods @@ -714,6 +714,10 @@ __END__ Wallet::Server - Wallet system server implementation +=for stopwords +keytabs metadata backend HOSTNAME ACL timestamp ACL's nul Allbery +backend-specific wallet-backend + =head1 SYNOPSIS use Wallet::Server; @@ -725,8 +729,8 @@ Wallet::Server - Wallet system server implementation Wallet::Server is the top-level class that implements the wallet server. The wallet is a system for storing, generating, and retrieving secure information such as Kerberos keytabs. The server maintains metadata about -the objects, checks access against ACLs, and dispatches requests for objects -to backend implementations for that object type. +the objects, checks access against ACLs, and dispatches requests for +objects to backend implementations for that object type. Wallet::Server is normally instantiated and used by B, a thin wrapper around this object that determines the authenticated remote @@ -734,8 +738,8 @@ user and gets user input and then calls the appropriate method of this object. To use this object, several configuration variables must be set (at least -the database configuration). For information on those variables and how to -set them, see Wallet::Config(3). +the database configuration). For information on those variables and how +to set them, see Wallet::Config(3). =head1 CLASS METHODS @@ -765,11 +769,12 @@ failure to get the error message. Gets or sets the ACL type ACL to ID for the object identified by TYPE and NAME. ACL should be one of C, C, C, C, or -C. If ID is not given, returns the current setting of that ACL as a -numeric ACL ID or undef if that ACL isn't set or on failure. To distinguish -between an ACL that isn't set and a failure to retrieve the ACL, the caller -should call error() after an undef return. If error() also returns undef, -that ACL wasn't set; otherwise, error() will return the error message. +C. If ID is not given, returns the current setting of that ACL as +a numeric ACL ID or undef if that ACL isn't set or on failure. To +distinguish between an ACL that isn't set and a failure to retrieve the +ACL, the caller should call error() after an undef return. If error() +also returns undef, that ACL wasn't set; otherwise, error() will return +the error message. If ID is given, sets the specified ACL to ID, which can be either the name of an ACL or a numeric ACL ID. To set an ACL, the current user must be @@ -798,64 +803,65 @@ failure. Destroys the ACL identified by ID, which may be either the ACL name or its numeric ID. This call will fail if the ACL is still referenced by any -object. The ADMIN ACL may not be destroyed. To destroy an ACL, the current -user must be authorized by the ADMIN ACL. Returns true on success and false -on failure. +object. The ADMIN ACL may not be destroyed. To destroy an ACL, the +current user must be authorized by the ADMIN ACL. Returns true on success +and false on failure. =item acl_history(ID) -Returns the history of the ACL identified by ID, which may be either the ACL -name or its numeric ID. To see the history of an ACL, the current user must -be authorized by the ADMIN ACL. Each change that modifies the ACL (not -counting changes in 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. Returns undef on failure. +Returns the history of the ACL identified by ID, which may be either the +ACL name or its numeric ID. To see the history of an ACL, the current +user must be authorized by the ADMIN ACL. Each change that modifies the +ACL (not counting changes in 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. Returns +undef on failure. =item acl_remove(ID, SCHEME, IDENTIFIER) Removes from the ACL identified by ID the entry matching SCHEME and IDENTIFIER. ID may be either the name of the ACL or its numeric ID. The last entry in the ADMIN ACL cannot be removed. To remove an entry from an -ACL, the current user must be authorized by the ADMIN ACL. Returns true on -success and false on failure. +ACL, the current user must be authorized by the ADMIN ACL. Returns true +on success and false on failure. =item acl_rename(OLD, NEW) Renames the ACL identified by OLD to NEW. This changes the human-readable -name, not the underlying numeric ID, so the ACL's associations with objects -will be unchanged. The ADMIN ACL may not be renamed. OLD may be either the -current name or the numeric ID. NEW must not be all-numeric. To rename an -ACL, the current user must be authorized by the ADMIN ACL. Returns true on -success and false on failure. +name, not the underlying numeric ID, so the ACL's associations with +objects will be unchanged. The ADMIN ACL may not be renamed. OLD may be +either the current name or the numeric ID. NEW must not be all-numeric. +To rename an ACL, the current user must be authorized by the ADMIN ACL. +Returns true on success and false on failure. =item acl_show(ID) Returns a human-readable description, including membership, of the ACL identified by ID, which may be either the ACL name or its numeric ID. To -show an ACL, the current user must be authorized by the ADMIN ACL (although -be aware that anyone with show access to an object can see the membership of -ACLs associated with that object through the show() method). Returns the -human-readable description on success and undef on failure. +show an ACL, the current user must be authorized by the ADMIN ACL +(although be aware that anyone with show access to an object can see the +membership of ACLs associated with that object through the show() method). +Returns the human-readable description on success and undef on failure. =item attr(TYPE, NAME, ATTRIBUTE [, VALUE ...]) Sets or retrieves a given object attribute. Attributes are used to store -backend-specific information for a particular object type and ATTRIBUTE must -be an attribute type known to the underlying object implementation. +backend-specific information for a particular object type and ATTRIBUTE +must be an attribute type known to the underlying object implementation. If VALUE is not given, returns the values of that attribute, if any, as a list. On error, returns the empty list. To distinguish between an error -and an empty return, call error() afterwards. It is guaranteed to return -undef unless there was an error. To retrieve an attribute setting, the user -must be authorized by the ADMIN ACL, the show ACL if set, or the owner ACL -if the show ACL is not set. +and an empty return, call error() afterward. It is guaranteed to return +undef unless there was an error. To retrieve an attribute setting, the +user must be authorized by the ADMIN ACL, the show ACL if set, or the +owner ACL if the show ACL is not set. -If VALUE is given, sets the given ATTRIBUTE values to VALUE, which is one or -more attribute values. Pass the empty string as the only VALUE to clear the -attribute values. Returns true on success and false on failure. To set an -attribute value, the user must be authorized by the ADMIN ACL, the store ACL -if set, or the owner ACL if the store ACL is not set. +If VALUE is given, sets the given ATTRIBUTE values to VALUE, which is one +or more attribute values. Pass the empty string as the only VALUE to +clear the attribute values. Returns true on success and false on failure. +To set an attribute value, the user must be authorized by the ADMIN ACL, +the store ACL if set, or the owner ACL if the store ACL is not set. =item autocreate(TYPE, NAME) @@ -877,9 +883,9 @@ for the existence of the object. =item create(TYPE, NAME) -Creates a new object of type TYPE and name NAME. TYPE must be a recognized -type for which the wallet system has a backend implementation. Returns true -on success and false on failure. +Creates a new object of type TYPE and name NAME. TYPE must be a +recognized type for which the wallet system has a backend implementation. +Returns true on success and false on failure. To create an object using this method, the current user must be authorized by the ADMIN ACL. Use autocreate() to create objects based on the default @@ -888,18 +894,18 @@ owner as determined by the wallet configuration. =item destroy(TYPE, NAME) Destroys the object identified by TYPE and NAME. This destroys any data -that the wallet had saved about the object, may remove the underlying object -from other external systems, and destroys the wallet database entry for the -object. To destroy an object, the current user must be authorized by the -ADMIN ACL or the destroy ACL on the object; the owner ACL is not sufficient. -Returns true on success and false on failure. +that the wallet had saved about the object, may remove the underlying +object from other external systems, and destroys the wallet database entry +for the object. To destroy an object, the current user must be authorized +by the ADMIN ACL or the destroy ACL on the object; the owner ACL is not +sufficient. Returns true on success and false on failure. =item dbh() -Returns the database handle of a Wallet::Server object. This is used mostly -for testing; normally, clients should perform all actions through the -Wallet::Server object to ensure that authorization and history logging is -done properly. +Returns the database handle of a Wallet::Server object. This is used +mostly for testing; normally, clients should perform all actions through +the Wallet::Server object to ensure that authorization and history logging +is done properly. =item error() @@ -909,12 +915,12 @@ after an undef return from any other instance method. =item expires(TYPE, NAME [, EXPIRES]) -Gets or sets the expiration for the object identified by TYPE and NAME. If -EXPIRES is not given, returns the current expiration or undef if no -expiration is set or on an error. To distinguish between an expiration that -isn't set and a failure to retrieve the expiration, the caller should call -error() after an undef return. If error() also returns undef, that ACL -wasn't set; otherwise, error() will return the error message. +Gets or sets the expiration for the object identified by TYPE and NAME. +If EXPIRES is not given, returns the current expiration or undef if no +expiration is set or on an error. To distinguish between an expiration +that isn't set and a failure to retrieve the expiration, the caller should +call error() after an undef return. If error() also returns undef, that +ACL wasn't set; otherwise, error() will return the error message. If EXPIRES is given, sets the expiration to EXPIRES. EXPIRES must be in the format C, although the time portion may be @@ -924,23 +930,23 @@ ADMIN ACL. Returns true for success and false for failure. =item flag_clear(TYPE, NAME, FLAG) -Clears the flag FLAG on the object identified by TYPE and NAME. To clear a -flag, the current user must be authorized by the ADMIN ACL or the flags ACL -on the object. +Clears the flag FLAG on the object identified by TYPE and NAME. To clear +a flag, the current user must be authorized by the ADMIN ACL or the flags +ACL on the object. =item flag_set(TYPE, NAME, FLAG) Sets the flag FLAG on the object identified by TYPE and NAME. To set a -flag, the current user must be authorized by the ADMIN ACL or the flags ACL -on the object. +flag, the current user must be authorized by the ADMIN ACL or the flags +ACL on the object. =item get(TYPE, NAME) Returns the data associated with the object identified by TYPE and NAME. -Depending on the object TYPE, this may generate new data and invalidate any -existing data or it may return data previously stored or generated. Note -that this data may be binary and may contain nul characters. To get an -object, the current user must either be authorized by the owner ACL or +Depending on the object TYPE, this may generate new data and invalidate +any existing data or it may return data previously stored or generated. +Note that this data may be binary and may contain nul characters. To get +an object, the current user must either be authorized by the owner ACL or authorized by the get ACL; however, if the get ACL is set, the owner ACL will not be checked. Being a member of the ADMIN ACL does not provide any special privileges to get objects. @@ -950,48 +956,49 @@ between undef and the empty string, which is valid object data. =item history(TYPE, NAME) -Returns (as a string) the human-readable history of the object identified by -TYPE and NAME, or undef on error. To see the object history, the current -user must be a member of the ADMIN ACL, authorized by the show ACL, or -authorized by the owner ACL; however, if the show ACL is set, the owner ACL -will not be checked. +Returns (as a string) the human-readable history of the object identified +by TYPE and NAME, or undef on error. To see the object history, the +current user must be a member of the ADMIN ACL, authorized by the show +ACL, or authorized by the owner ACL; however, if the show ACL is set, the +owner ACL will not be checked. =item owner(TYPE, NAME [, OWNER]) -Gets or sets the owner for the object identified by TYPE and NAME. If OWNER -is not given, returns the current owner as a numeric ACL ID or undef if no -owner is set or on an error. To distinguish between an owner that isn't set -and a failure to retrieve the owner, the caller should call error() after an -undef return. If error() also returns undef, that ACL wasn't set; -otherwise, error() will return the error message. +Gets or sets the owner for the object identified by TYPE and NAME. If +OWNER is not given, returns the current owner as a numeric ACL ID or undef +if no owner is set or on an error. To distinguish between an owner that +isn't set and a failure to retrieve the owner, the caller should call +error() after an undef return. If error() also returns undef, that ACL +wasn't set; otherwise, error() will return the error message. -If OWNER is given, sets the owner to OWNER, which may be either the name of -an ACL or a numeric ACL ID. To set an owner, the current user must be +If OWNER is given, sets the owner to OWNER, which may be either the name +of an ACL or a numeric ACL ID. To set an owner, the current user must be authorized by the ADMIN ACL. Returns true for success and false for failure. -The owner of an object is permitted to get, store, and show that object, but -cannot destroy or set flags on that object without being listed on those -ACLs as well. +The owner of an object is permitted to get, store, and show that object, +but cannot destroy or set flags on that object without being listed on +those ACLs as well. =item show(TYPE, NAME) -Returns (as a string) a human-readable representation of the metadata stored -for the object identified by TYPE and NAME, or undef on error. Included is -the metadata and entries of any ACLs associated with the object. To show an -object, the current user must be a member of the ADMIN ACL, authorized by -the show ACL, or authorized by the owner ACL; however, if the show ACL is -set, the owner ACL will not be checked. +Returns (as a string) a human-readable representation of the metadata +stored for the object identified by TYPE and NAME, or undef on error. +Included is the metadata and entries of any ACLs associated with the +object. To show an object, the current user must be a member of the ADMIN +ACL, authorized by the show ACL, or authorized by the owner ACL; however, +if the show ACL is set, the owner ACL will not be checked. =item store(TYPE, NAME, DATA) -Stores DATA for the object identified with TYPE and NAME for later retrieval -with get. Not all object types support this. Note that DATA may be binary -and may contain nul characters. To store an object, the current user must -either be authorized by the owner ACL or authorized by the store ACL; -however, if the store ACL is set, the owner ACL is not checked. Being a -member of the ADMIN ACL does not provide any special privileges to store -objects. Returns true on success and false on failure. +Stores DATA for the object identified with TYPE and NAME for later +retrieval with get. Not all object types support this. Note that DATA +may be binary and may contain nul characters. To store an object, the +current user must either be authorized by the owner ACL or authorized by +the store ACL; however, if the store ACL is set, the owner ACL is not +checked. Being a member of the ADMIN ACL does not provide any special +privileges to store objects. Returns true on success and false on +failure. =back @@ -999,8 +1006,8 @@ objects. Returns true on success and false on failure. wallet-backend(8) -This module is part of the wallet system. The current version is available -from L. +This module is part of the wallet system. The current version is +available from L. =head1 AUTHOR diff --git a/perl/t/pod-spelling.t b/perl/t/pod-spelling.t new file mode 100755 index 0000000..d3ab858 --- /dev/null +++ b/perl/t/pod-spelling.t @@ -0,0 +1,75 @@ +#!/usr/bin/perl -w +# +# Check for spelling errors in POD documentation +# +# Checks all POD files in the tree for spelling problems using Pod::Spell and +# either aspell or ispell. aspell is preferred. This test is disabled unless +# RRA_MAINTAINER_TESTS is set, since spelling dictionaries vary too much +# between environments. +# +# Copyright 2008, 2009 Russ Allbery +# +# This program is free software; you may redistribute it and/or modify it +# under the same terms as Perl itself. + +use strict; +use Test::More; + +# Skip all spelling tests unless the maintainer environment variable is set. +plan skip_all => 'Spelling tests only run for maintainer' + unless $ENV{RRA_MAINTAINER_TESTS}; + +# Load required Perl modules. +eval 'use Test::Pod 1.00'; +plan skip_all => 'Test::Pod 1.00 required for testing POD' if $@; +eval 'use Pod::Spell'; +plan skip_all => 'Pod::Spell required to test POD spelling' if $@; + +# Locate a spell-checker. hunspell is not currently supported due to its lack +# of support for contractions (at least in the version in Debian). +my @spell; +my %options = (aspell => [ qw(-d en_US --home-dir=./ list) ], + ispell => [ qw(-d american -l -p /dev/null) ]); +SEARCH: for my $program (qw/aspell ispell/) { + for my $dir (split ':', $ENV{PATH}) { + if (-x "$dir/$program") { + @spell = ("$dir/$program", @{ $options{$program} }); + } + last SEARCH if @spell; + } +} +plan skip_all => 'aspell or ispell required to test POD spelling' + unless @spell; + +# Prerequisites are satisfied, so we're going to do some testing. Figure out +# what POD files we have and from that develop our plan. +$| = 1; +my @pod = all_pod_files (); +plan tests => scalar @pod; + +# Finally, do the checks. +for my $pod (@pod) { + my $child = open (CHILD, '-|'); + if (not defined $child) { + die "Cannot fork: $!\n"; + } elsif ($child == 0) { + my $pid = open (SPELL, '|-', @spell) or die "Cannot run @spell: $!\n"; + open (POD, '<', $pod) or die "Cannot open $pod: $!\n"; + my $parser = Pod::Spell->new; + $parser->parse_from_filehandle (\*POD, \*SPELL); + close POD; + close SPELL; + exit ($? >> 8); + } else { + my @words = ; + close CHILD; + SKIP: { + skip "@spell failed for $pod", 1 unless $? == 0; + for (@words) { + s/^\s+//; + s/\s+$//; + } + is ("@words", '', $pod); + } + } +} diff --git a/perl/t/pod.t b/perl/t/pod.t index e9aa0a8..c467b82 100755 --- a/perl/t/pod.t +++ b/perl/t/pod.t @@ -1,16 +1,14 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # -# t/pod.t -- Test POD formatting for the wallet Perl modules. +# Test POD formatting for the wallet Perl modules. # # Written by Russ Allbery -# Copyright 2007 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. +use strict; +use Test::More; eval 'use Test::Pod 1.00'; -if ($@) { - print "1..1\n"; - print "ok 1 # skip - Test::Pod 1.00 required for testing POD\n"; - exit; -} +plan skip_all => 'Test::Pod 1.00 required for testing POD' if $@; all_pod_files_ok (); -- cgit v1.2.3 From 9336216818041c1a891a734f3dd431e7fbc50bcf Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Thu, 18 Feb 2010 14:18:22 -0800 Subject: Move stub fork_callback() into parent class Move the stub fork_callback method into Wallet::Kadmin and make both Wallet::Kadmin::Heimdal and Wallet::Kadmin::MIT inherit from Wallet::Kadmin. Add POD documentation for fork_callback. --- perl/Wallet/Kadmin.pm | 27 ++++++++++++++++++++++----- perl/Wallet/Kadmin/Heimdal.pm | 10 ++++------ perl/Wallet/Kadmin/MIT.pm | 5 ++++- 3 files changed, 30 insertions(+), 12 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index b653f87..65adc83 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -26,6 +26,11 @@ $VERSION = '0.03'; # Public methods ############################################################################## +# 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 { } + # 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. @@ -78,9 +83,8 @@ specific type of Kerberos implementation, such as MIT Kerberos or Heimdal, and provide a standard set of API calls used to interact with that implementation's kadmin interface. -The class simply uses Wallet::Config to find which type of kadmind we have -requested to use, and then returns an object to use for interacting with -that kadmind. +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. 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 @@ -92,18 +96,31 @@ To use this object, several configuration parameters must be set. See Wallet::Config(3) for details on those configuration parameters and information about how to set wallet configuration. -=head1 METHODS +=head1 CLASS METHODS =over 4 =item new() Finds the proper Kerberos implementation and calls the new() constructor -for that implementation's module, returning the result. If the +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 + +=over 4 + +=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. + +=back + =head1 SEE ALSO kadmin(8), Wallet::Config(3), Wallet::Object::Keytab(3), wallet-backend(8) diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index 2ad35e3..30b1e52 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -13,10 +13,13 @@ package Wallet::Kadmin::Heimdal; require 5.006; use strict; -use vars qw($VERSION); +use vars qw(@ISA $VERSION); use Heimdal::Kadm5 qw(KRB5_KDB_DISALLOW_ALL_TIX); use Wallet::Config (); +use Wallet::Kadmin (); + +@ISA = qw(Wallet::Kadmin); # 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 @@ -48,11 +51,6 @@ sub canonicalize_principal { return $principal; } -# Set a callback to be called for forked kadmin processes. This does nothing -# for Heimdal, as we're not forking anything, but remains for compatibility -# with the MIT kadmin module. -sub fork_callback { } - ############################################################################## # kadmin Interaction ############################################################################## diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index 8449868..f181739 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -15,9 +15,12 @@ package Wallet::Kadmin::MIT; require 5.006; use strict; -use vars qw($VERSION); +use vars qw(@ISA $VERSION); use Wallet::Config (); +use Wallet::Kadmin (); + +@ISA = qw(Wallet::Kadmin); # 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 -- cgit v1.2.3 From 52ee9b9285f04551cfdcbde2b3b6293a706ca982 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Thu, 18 Feb 2010 16:14:51 -0800 Subject: Lift the error method into Wallet::Kadmin Take advantage of inheritance by providing the error method in Wallet::Kadmin rather than separately in both the subclasses. --- perl/Wallet/Kadmin.pm | 35 ++++++++++++++++++++++++++++++----- perl/Wallet/Kadmin/Heimdal.pm | 12 ------------ perl/Wallet/Kadmin/MIT.pm | 12 ------------ 3 files changed, 30 insertions(+), 29 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 65adc83..78b72cd 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -26,11 +26,6 @@ $VERSION = '0.03'; # Public methods ############################################################################## -# 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 { } - # 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. @@ -53,6 +48,23 @@ sub new { 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__ @@ -112,6 +124,19 @@ implementation is not recognized or set, die with an error message. =over 4 +=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> 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 fork_callback(CALLBACK) If the module has to fork an external process for some reason, such as a diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index 30b1e52..3047b2f 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -30,18 +30,6 @@ $VERSION = '0.03'; # Utility functions ############################################################################## -# 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}; -} - # Add the realm to the end of the principal if no realm is currently present. sub canonicalize_principal { my ($self, $principal) = @_; diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index a7ccf99..9dc101e 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -31,18 +31,6 @@ $VERSION = '0.02'; # Utility functions ############################################################################## -# 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. sub fork_callback { my ($self, $callback) = @_; -- cgit v1.2.3 From ca0930ed6a57f1b584fdf13307337c8e966d442c Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Thu, 18 Feb 2010 17:28:56 -0800 Subject: Move Wallet::Kadmin documentation into the parent class Rather than duplicating the API documentation in both ::Heimdal and ::MIT, move it into Wallet::Kadmin and just reference that from the subclasses. Add documentation for exists(), since that's part of the public API. Move a few methods around and fix a few other minor documentation differences. --- perl/Wallet/Kadmin.pm | 66 +++++++++++++++++++++++++++---------- perl/Wallet/Kadmin/Heimdal.pm | 55 +++++-------------------------- perl/Wallet/Kadmin/MIT.pm | 76 +++++++++---------------------------------- 3 files changed, 74 insertions(+), 123 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 78b72cd..a06e1e2 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -1,4 +1,4 @@ -# Wallet::Kadmin -- Kadmin module wrapper for the wallet. +# Wallet::Kadmin -- Kerberos administration API for wallet keytab backend. # # Written by Jon Robertson # Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University @@ -73,15 +73,16 @@ __END__ ############################################################################## =for stopwords -Kadmin keytabs keytab Heimdal API kadmind kadmin +backend Kadmin keytabs keytab Heimdal API kadmind kadmin KDC ENCTYPES +enctypes enctype Allbery =head1 NAME -Wallet::Kadmin - Kadmin module wrapper for wallet keytabs +Wallet::Kadmin - Kerberos administration API for wallet keytab backend =head1 SYNOPSIS - my $kadmin = Wallet::Kadmin->new (); + my $kadmin = Wallet::Kadmin->new; $kadmin->addprinc ("host/shell.example.com"); $kadmin->ktadd ("host/shell.example.com", "aes256-cts-hmac-sha1-96"); my $exists = $kadmin->exists ("host/oldshell.example.com"); @@ -89,21 +90,15 @@ Wallet::Kadmin - Kadmin module wrapper for wallet keytabs =head1 DESCRIPTION -Wallet::Kadmin is a wrapper to modules that provide an interface for -keytab integration with wallet. Each module is meant to interface with a -specific type of Kerberos implementation, such as MIT Kerberos or Heimdal, -and provide a standard set of API calls used to interact with that -implementation's kadmin interface. +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. - -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 be created in Kerberos and then a -keytab is generated and stored in a file on disk. - To use this object, several configuration parameters must be set. See Wallet::Config(3) for details on those configuration parameters and information about how to set wallet configuration. @@ -122,8 +117,25 @@ implementation is not recognized or set, die with an error message. =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 addprinc(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 delprinc(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 @@ -137,6 +149,12 @@ 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 @@ -144,6 +162,20 @@ 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 ktadd(PRINCIPAL, FILE, ENCTYPES) + +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 be created in Kerberos and then a +keytab is generated and stored in a file on disk. + +ktadd() creates a new keytab for the given principal, storing it in the +given file and limited to the enctypes supplied. The enctype values must +be enctype strings recognized by the Kerberos implementation (strings like +C or C). Returns true on success +and false on failure. + =back =head1 SEE ALSO @@ -155,6 +187,6 @@ available from L. =head1 AUTHORS -Jon Robertson +Jon Robertson and Russ Allbery =cut diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index 2d393e2..d59b33c 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -1,4 +1,4 @@ -# Wallet::Kadmin::Heimdal -- Heimdal Kadmin interactions for the wallet. +# Wallet::Kadmin::Heimdal -- Wallet Kerberos administration API for Heimdal. # # Written by Jon Robertson # Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University @@ -204,15 +204,15 @@ __END__ ############################################################################## =for stopwords -keytabs keytab kadmin enctypes API ENCTYPES enctype Allbery Heimdal +keytabs keytab kadmin KDC API Allbery Heimdal =head1 NAME -Wallet::Kadmin::Heimdal - Heimdal admin interactions for wallet keytabs +Wallet::Kadmin::Heimdal - Wallet Kerberos administration API for Heimdal =head1 SYNOPSIS - my $kadmin = Wallet::Kadmin::MIT->new (); + my $kadmin = Wallet::Kadmin::Heimdal->new; $kadmin->addprinc ("host/shell.example.com"); $kadmin->ktadd ("host/shell.example.com", "aes256-cts-hmac-sha1-96"); my $exists = $kadmin->exists ("host/oldshell.example.com"); @@ -220,55 +220,18 @@ Wallet::Kadmin::Heimdal - Heimdal admin interactions for wallet keytabs =head1 DESCRIPTION -Wallet::Kadmin::Heimdal is an interface for keytab integration with the -wallet, specifically for using kadmin to create, delete, and add enctypes -to keytabs. It implements the wallet kadmin API and provides the -necessary glue to Heimdal installs for each of these functions, while -allowing the wallet to keep the details of what type of Kerberos -installation is being used abstracted. - -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 be created in Kerberos and then a -keytab is generated and stored in a file on disk. +Wallet::Kadmin::Heimdal implements the Wallet::Kadmin API for Heimdal, +providing an interface to create and delete principals and create keytabs. +It provides the API documented in Wallet::Kadmin(3) for a Heimdal KDC. To use this object, several configuration parameters must be set. See Wallet::Config(3) for details on those configuration parameters and information about how to set wallet configuration. -=head1 METHODS - -=over 4 - -=item addprinc(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, or throws an error if there was a failure in adding the -principal. If the principal already exists, return true as we are -bringing our expectations in line with reality. - -=item addprinc(PRINCIPAL) - -Removes a principal with the given name. Returns true on success, or -throws an error if there was a failure in removing the principal. If the -principal does not exist, return true as we are bringing our expectations -in line with reality. - -=item ktadd(PRINCIPAL, FILE, ENCTYPES) - -Creates a new keytab for the given principal, as the given file, limited -to the enctypes supplied. The enctype values must be enctype strings -recognized by Kerberos (strings like C or -C). An error is thrown on failure or if the creation fails, -otherwise true is returned. - -=back - =head1 SEE ALSO -kadmin(8), Wallet::Config(3), Wallet::Object::Keytab(3), wallet-backend(8) +kadmin(8), Wallet::Config(3), Wallet::Kadmin(3), +Wallet::Object::Keytab(3), wallet-backend(8) This module is part of the wallet system. The current version is available from L. diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index 9dc101e..1ab8b1d 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -1,4 +1,4 @@ -# Wallet::Kadmin::MIT -- MIT Kadmin interactions for the wallet. +# Wallet::Kadmin::MIT -- Wallet Kerberos administration API for MIT. # # Written by Russ Allbery # Pulled into a module by Jon Robertson @@ -27,16 +27,6 @@ use Wallet::Kadmin (); # that it will sort properly. $VERSION = '0.02'; -############################################################################## -# Utility functions -############################################################################## - -# Set a callback to be called for forked kadmin processes. -sub fork_callback { - my ($self, $callback) = @_; - $self->{fork_callback} = $callback; -} - ############################################################################## # kadmin Interaction ############################################################################## @@ -99,6 +89,12 @@ sub kadmin { # Public interfaces ############################################################################## +# Set a callback to be called for forked kadmin processes. +sub fork_callback { + my ($self, $callback) = @_; + $self->{fork_callback} = $callback; +} + # Check whether a given principal already exists in Kerberos. Returns true if # so, false otherwise. Returns undef if kadmin fails, with the error already # set by kadmin. @@ -196,10 +192,6 @@ sub delprinc { return 1; } -############################################################################## -# Documentation -############################################################################## - # Create a new MIT kadmin object. Very empty for the moment, but later it # will probably fill out if we go to using a module rather than calling # kadmin directly. @@ -218,15 +210,15 @@ __END__ ############################################################################## =for stopwords -keytabs keytab kadmin enctype enctypes API ENCTYPES Allbery +keytabs keytab kadmin KDC API Allbery =head1 NAME -Wallet::Kadmin::MIT - MIT admin interactions for wallet keytabs +Wallet::Kadmin::MIT - Wallet Kerberos administration API for MIT =head1 SYNOPSIS - my $kadmin = Wallet::Kadmin::MIT->new (); + my $kadmin = Wallet::Kadmin::MIT->new; $kadmin->addprinc ("host/shell.example.com"); $kadmin->ktadd ("host/shell.example.com", "aes256-cts-hmac-sha1-96"); my $exists = $kadmin->exists ("host/oldshell.example.com"); @@ -234,52 +226,15 @@ Wallet::Kadmin::MIT - MIT admin interactions for wallet keytabs =head1 DESCRIPTION -Wallet::Kadmin::MIT is an interface for keytab integration with the -wallet, specifically for using kadmin to create, delete, and add enctypes -to keytabs. It implements the wallet kadmin API and provides the -necessary glue to MIT Kerberos installs for each of these functions, while -allowing the wallet to keep the details of what type of Kerberos -installation is being used abstracted. - -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 be created in Kerberos and then a -keytab is generated and stored in a file on disk. +Wallet::Kadmin::MIT implements the Wallet::Kadmin API for MIT Kerberos, +providing an interface to create and delete principals and create keytabs. +It provides the API documented in Wallet::Kadmin(3) for an MIT Kerberos +KDC. To use this object, several configuration parameters must be set. See Wallet::Config(3) for details on those configuration parameters and information about how to set wallet configuration. -=head1 METHODS - -=over 4 - -=item addprinc(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, or throws an error if there was a failure in adding the -principal. If the principal already exists, return true as we are -bringing our expectations in line with reality. - -=item delprinc(PRINCIPAL) - -Removes a principal with the given name. Returns true on success, or -throws an error if there was a failure in removing the principal. If the -principal does not exist, return true as we are bringing our expectations -in line with reality. - -=item ktadd(PRINCIPAL, FILE, ENCTYPES) - -Creates a new keytab for the given principal, as the given file, limited -to the enctypes supplied. The enctype values must be enctype strings -recognized by Kerberos (strings like C or -C). An error is thrown on failure or if the creation fails, -otherwise true is returned. - -=back - =head1 LIMITATIONS Currently, this implementation calls an external B program rather @@ -289,7 +244,8 @@ output of B ever changes. =head1 SEE ALSO -kadmin(8), Wallet::Config(3), Wallet::Object::Keytab(3), wallet-backend(8) +kadmin(8), Wallet::Config(3), Wallet::Kadmin(3), +Wallet::Object::Keytab(3), wallet-backend(8) This module is part of the wallet system. The current version is available from L. -- cgit v1.2.3 From 2651ef4352c8cc782c4e0f3175257f7bb0c1e495 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Thu, 18 Feb 2010 18:03:09 -0800 Subject: Rename functions in Wallet::Kadmin API Now that we support multiple versions of Kerberos, use generic names for the functions in the Wallet::Kadmin interface rather than the commands from the MIT kadmin interface. --- TODO | 4 ---- perl/Wallet/Kadmin.pm | 14 +++++++------- perl/Wallet/Kadmin/Heimdal.pm | 12 ++++++------ perl/Wallet/Kadmin/MIT.pm | 12 ++++++------ perl/Wallet/Object/Keytab.pm | 17 ++++++----------- perl/t/kadmin.t | 14 +++++++------- perl/t/keytab.t | 4 ++-- 7 files changed, 34 insertions(+), 43 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/TODO b/TODO index bfc7910..4ad1b1e 100644 --- a/TODO +++ b/TODO @@ -2,12 +2,8 @@ Release 0.10: -* Remove stub fork hook from Wallet::Kadmin::MIT. - * Handle unchanging support for Heimdal. -* Fix the Wallet::Kadmin API to use more generic function names. - * Move reporting code from Wallet::Admin to Wallet::Report. * Refactor attribute handling code in Wallet::Object::Keytab, move to diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index a06e1e2..21678ca 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -73,7 +73,7 @@ __END__ ############################################################################## =for stopwords -backend Kadmin keytabs keytab Heimdal API kadmind kadmin KDC ENCTYPES +backend Kadmin keytabs keytab Heimdal API kadmind kadmin KDC ENCTYPE enctypes enctype Allbery =head1 NAME @@ -83,10 +83,10 @@ Wallet::Kadmin - Kerberos administration API for wallet keytab backend =head1 SYNOPSIS my $kadmin = Wallet::Kadmin->new; - $kadmin->addprinc ("host/shell.example.com"); - $kadmin->ktadd ("host/shell.example.com", "aes256-cts-hmac-sha1-96"); + $kadmin->create ("host/foo.example.com"); + $kadmin->keytab ("host/foo.example.com", "aes256-cts-hmac-sha1-96"); my $exists = $kadmin->exists ("host/oldshell.example.com"); - $kadmin->delprinc ("host/oldshell.example.com") if $exists; + $kadmin->destroy ("host/oldshell.example.com") if $exists; =head1 DESCRIPTION @@ -123,14 +123,14 @@ appropriate for the configured Kerberos implementation. =over 4 -=item addprinc(PRINCIPAL) +=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 delprinc(PRINCIPAL) +=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 @@ -162,7 +162,7 @@ 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 ktadd(PRINCIPAL, FILE, ENCTYPES) +=item keytab(PRINCIPAL, FILE [, ENCTYPE ... ]) 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 diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index d59b33c..0ac8cd9 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -59,7 +59,7 @@ sub exists { # Create a principal in Kerberos. If there is an error, return undef and set # the error. Return 1 on success or the principal already existing. -sub addprinc { +sub create { my ($self, $principal) = @_; $principal = $self->canonicalize_principal ($principal); my $exists = eval { $self->exists ($principal) }; @@ -97,7 +97,7 @@ sub addprinc { # optionally a list of encryption types to which to limit the keytab. Return # true if successful, false otherwise. If the keytab creation fails, sets the # error. -sub ktadd { +sub keytab { my ($self, $principal, $file, @enctypes) = @_; $principal = $self->canonicalize_principal ($principal); @@ -155,7 +155,7 @@ sub ktadd { # Delete a principal from Kerberos. Return true if successful, false # otherwise. If the deletion fails, sets the error. If the principal doesn't # exist, return success; we're bringing reality in line with our expectations. -sub delprinc { +sub destroy { my ($self, $principal) = @_; $principal = $self->canonicalize_principal ($principal); my $exists = eval { $self->exists ($principal) }; @@ -213,10 +213,10 @@ Wallet::Kadmin::Heimdal - Wallet Kerberos administration API for Heimdal =head1 SYNOPSIS my $kadmin = Wallet::Kadmin::Heimdal->new; - $kadmin->addprinc ("host/shell.example.com"); - $kadmin->ktadd ("host/shell.example.com", "aes256-cts-hmac-sha1-96"); + $kadmin->create ("host/foo.example.com"); + $kadmin->keytab ("host/foo.example.com", "aes256-cts-hmac-sha1-96"); my $exists = $kadmin->exists ("host/oldshell.example.com"); - $kadmin->delprinc ("host/oldshell.example.com") if $exists; + $kadmin->destroy ("host/oldshell.example.com") if $exists; =head1 DESCRIPTION diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index 1ab8b1d..9ab575c 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -116,7 +116,7 @@ sub exists { # Create a principal in Kerberos. Sets the error and returns undef on failure, # and returns 1 on either success or the principal already existing. -sub addprinc { +sub create { my ($self, $principal) = @_; unless ($self->valid_principal ($principal)) { $self->error ("invalid principal name $principal"); @@ -141,7 +141,7 @@ sub addprinc { # optionally a list of encryption types to which to limit the keytab. Return # true if successful, false otherwise. If the keytab creation fails, sets the # error. -sub ktadd { +sub keytab { my ($self, $principal, $file, @enctypes) = @_; unless ($self->valid_principal ($principal)) { $self->error ("invalid principal name: $principal"); @@ -168,7 +168,7 @@ sub ktadd { # Delete a principal from Kerberos. Return true if successful, false # otherwise. If the deletion fails, sets the error. If the principal doesn't # exist, return success; we're bringing reality in line with our expectations. -sub delprinc { +sub destroy { my ($self, $principal) = @_; unless ($self->valid_principal ($principal)) { $self->error ("invalid principal name: $principal"); @@ -219,10 +219,10 @@ Wallet::Kadmin::MIT - Wallet Kerberos administration API for MIT =head1 SYNOPSIS my $kadmin = Wallet::Kadmin::MIT->new; - $kadmin->addprinc ("host/shell.example.com"); - $kadmin->ktadd ("host/shell.example.com", "aes256-cts-hmac-sha1-96"); + $kadmin->create ("host/foo.example.com"); + $kadmin->keytab ("host/foo.example.com", "aes256-cts-hmac-sha1-96"); my $exists = $kadmin->exists ("host/oldshell.example.com"); - $kadmin->delprinc ("host/oldshell.example.com") if $exists; + $kadmin->destroy ("host/oldshell.example.com") if $exists; =head1 DESCRIPTION diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index 760280f..66c5e6a 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -289,7 +289,7 @@ sub create { my $callback = sub { $self->{dbh}->{InactiveDestroy} = 1 }; $kadmin->fork_callback ($callback); - if (not $kadmin->addprinc ($name)) { + if (not $kadmin->create ($name)) { die $kadmin->error, "\n"; } $self = $class->SUPER::create ($type, $name, $dbh, $creator, $host, $time); @@ -318,7 +318,7 @@ sub destroy { return; } my $kadmin = $self->{kadmin}; - if (not $kadmin->delprinc ($self->{name})) { + if (not $kadmin->destroy ($self->{name})) { $self->error ($kadmin->error); return; } @@ -350,7 +350,7 @@ sub get { unlink $file; my @enctypes = $self->attr ('enctypes'); my $kadmin = $self->{kadmin}; - if (not $kadmin->ktadd ($self->{name}, $file, @enctypes)) { + if (not $kadmin->keytab ($self->{name}, $file, @enctypes)) { $self->error ($kadmin->error); return; } @@ -520,19 +520,14 @@ used. =item KEYTAB_TMP/keytab. -The keytab is created in this file using C and then read into -memory. KEYTAB_TMP is set in the wallet configuration, and is the -process ID of the current process. The file is unlinked after being read. +The keytab is created in this file and then read into memory. KEYTAB_TMP +is set in the wallet configuration, and is the process ID of the +current process. The file is unlinked after being read. =back =head1 LIMITATIONS -Currently, when used with MIT Kerberos, this implementation calls an -external B program rather than using a native Perl module and -therefore requires B be installed and parses its output. It may -miss some error conditions if the output of B ever changes. - Only one Kerberos realm is supported for a given wallet implementation and all keytab objects stored must be in that realm. Keytab names in the wallet database do not have realm information. diff --git a/perl/t/kadmin.t b/perl/t/kadmin.t index 82e6edf..9c49995 100755 --- a/perl/t/kadmin.t +++ b/perl/t/kadmin.t @@ -83,15 +83,15 @@ SKIP: { $kadmin = eval { Wallet::Kadmin->new }; ok (defined $kadmin, 'Creating Wallet::Kadmin object succeeds'); is ($@, '', ' and there is no error'); - is ($kadmin->delprinc ('wallet/one'), 1, 'Deleting wallet/one works'); + is ($kadmin->destroy ('wallet/one'), 1, 'Deleting wallet/one works'); is ($kadmin->exists ('wallet/one'), 0, ' and it does not exist'); - # Create the principal and check that ktadd returns something. We'll + # Create the principal and check that keytab returns something. We'll # check the details of the return in the keytab check. - is ($kadmin->addprinc ('wallet/one'), 1, 'Creating wallet/one works'); + is ($kadmin->create ('wallet/one'), 1, 'Creating wallet/one works'); is ($kadmin->exists ('wallet/one'), 1, ' and it now exists'); unlink ('./tmp.keytab'); - is ($kadmin->ktadd ('wallet/one', './tmp.keytab'), 1, + is ($kadmin->keytab ('wallet/one', './tmp.keytab'), 1, ' and retrieving a keytab works'); ok (-s './tmp.keytab', ' and the resulting keytab is non-zero'); is (getcreds ('./tmp.keytab', "wallet/one\@$Wallet::Config::KEYTAB_REALM"), @@ -99,12 +99,12 @@ SKIP: { unlink ('./tmp.keytab'); # Delete the principal and confirm behavior. - is ($kadmin->delprinc ('wallet/one'), 1, 'Deleting principal works'); + is ($kadmin->destroy ('wallet/one'), 1, 'Deleting principal works'); is ($kadmin->exists ('wallet/one'), 0, ' and now it does not exist'); - is ($kadmin->ktadd ('wallet/one', './tmp.keytab'), undef, + is ($kadmin->keytab ('wallet/one', './tmp.keytab'), undef, ' and retrieving the keytab does not work'); ok (! -f './tmp.keytab', ' and no file was created'); like ($kadmin->error, qr%^error creating keytab for wallet/one%, ' and the right error message is set'); - is ($kadmin->delprinc ('wallet/one'), 1, ' and deleting it again works'); + is ($kadmin->destroy ('wallet/one'), 1, ' and deleting it again works'); } diff --git a/perl/t/keytab.t b/perl/t/keytab.t index 39be547..a14b63e 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -59,7 +59,7 @@ sub system_quiet { sub create { my ($principal) = @_; my $kadmin = Wallet::Kadmin->new; - return $kadmin->addprinc ($principal); + return $kadmin->create ($principal); } # Destroy a principal out of Kerberos. Only usable once the configuration has @@ -67,7 +67,7 @@ sub create { sub destroy { my ($principal) = @_; my $kadmin = Wallet::Kadmin->new; - return $kadmin->delprinc ($principal); + return $kadmin->destroy ($principal); } # Check whether a principal exists. MIT uses kvno and Heimdal uses kgetcred. -- cgit v1.2.3 From 1d249a09632c135c08a550319004b7a4e02d9e49 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Thu, 18 Feb 2010 18:04:50 -0800 Subject: Tiny coding style fix in Wallet::Kadmin --- perl/Wallet/Kadmin.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 21678ca..3ca531e 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -31,7 +31,7 @@ $VERSION = '0.03'; # from the specific Wallet::Kadmin::* module. sub new { my ($class) = @_; - my ($kadmin); + my $kadmin; if (not $Wallet::Config::KEYTAB_KRBTYPE) { die "keytab object implementation not configured\n"; } elsif (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'mit') { -- cgit v1.2.3 From a24d3ac3c7e8cb68fe2268f337a4edb599d5f881 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Thu, 18 Feb 2010 21:31:10 -0800 Subject: Support unchanging keytabs with Heimdal without remctl Heimdal supports retrieving a keytab containing the existing keys over the kadmin protocol. Move the support for using remctl to retrieve an existing keytab into Wallet::Kadmin::MIT and provide two separate methods in the Wallet::Kadmin interface: one which rekeys and one which doesn't. Implement the non-rekeying interface for Heimdal. Expand the test suite for the unchanging keytabs to include tests for the Heimdal method. --- TODO | 2 - perl/Wallet/Config.pm | 21 +++++-- perl/Wallet/Kadmin.pm | 43 ++++++++------ perl/Wallet/Kadmin/Heimdal.pm | 74 +++++++++++++++++++++--- perl/Wallet/Kadmin/MIT.pm | 68 +++++++++++++++++++--- perl/Wallet/Object/Keytab.pm | 49 +--------------- perl/t/kadmin.t | 4 +- perl/t/keytab.t | 127 ++++++++++++++++++++++++++++-------------- 8 files changed, 257 insertions(+), 131 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/TODO b/TODO index 92bd025..662ea47 100644 --- a/TODO +++ b/TODO @@ -2,8 +2,6 @@ Release 0.10: -* Handle unchanging support for Heimdal. - * Move reporting code from Wallet::Admin to Wallet::Report. * Check whether we can just drop the realm restriction on keytabs and diff --git a/perl/Wallet/Config.pm b/perl/Wallet/Config.pm index c59d3e3..396bf7d 100644 --- a/perl/Wallet/Config.pm +++ b/perl/Wallet/Config.pm @@ -26,7 +26,8 @@ Wallet::Config - Configuration handling for the wallet server =for stopwords DBI DSN SQLite subdirectories KEYTAB keytab kadmind KDC add-ons kadmin DNS SRV kadmin keytabs remctl backend lowercased NETDB ACL NetDB unscoped -usernames rekey hostnames Allbery wallet-backend keytab-backend +usernames rekey hostnames Allbery wallet-backend keytab-backend Heimdal +rekeys =head1 SYNOPSIS @@ -313,11 +314,19 @@ our $KEYTAB_TMP; =head2 Retrieving Existing Keytabs -The keytab object backend optionally supports retrieving existing keys, -and hence keytabs, for Kerberos principals by contacting the KDC via -remctl and talking to B. This is enabled by setting the -C flag on keytab objects. To configure that support, set the -following variables. +Heimdal provides the choice, over the network protocol, of either +downloading the existing keys for a principal or generating new random +keys. MIT Kerberos does not; downloading a keytab over the kadmin +protocol always rekeys the principal. + +For MIT Kerberos, the keytab object backend therefore optionally supports +retrieving existing keys, and hence keytabs, for Kerberos principals by +contacting the KDC via remctl and talking to B. This is +enabled by setting the C flag on keytab objects. To configure +that support, set the following variables. + +This is not required for Heimdal; for Heimdal, setting the C +flag is all that's needed. =over 4 diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 3ca531e..f3c2895 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -83,10 +83,12 @@ Wallet::Kadmin - Kerberos administration API for wallet keytab backend =head1 SYNOPSIS my $kadmin = Wallet::Kadmin->new; - $kadmin->create ("host/foo.example.com"); - $kadmin->keytab ("host/foo.example.com", "aes256-cts-hmac-sha1-96"); - my $exists = $kadmin->exists ("host/oldshell.example.com"); - $kadmin->destroy ("host/oldshell.example.com") if $exists; + $kadmin->create ('host/foo.example.com'); + $kadmin->keytab_rekey ('host/foo.example.com', 'keytab', + 'aes256-cts-hmac-sha1-96'); + my $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 @@ -162,19 +164,26 @@ 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, FILE [, ENCTYPE ... ]) - -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 be created in Kerberos and then a -keytab is generated and stored in a file on disk. - -ktadd() creates a new keytab for the given principal, storing it in the -given file and limited to the enctypes supplied. The enctype values must -be enctype strings recognized by the Kerberos implementation (strings like -C or C). Returns true on success -and false on failure. +=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, FILE [, 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 or +C). If none are given, the KDC defaults will be used. +Returns true on success and false on failure. =back diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index 0ac8cd9..e066006 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -39,6 +39,23 @@ sub canonicalize_principal { return $principal; } +# Read the entirety of a possibly binary file and return the contents. If +# reading the file fails, set the error message and return undef. +sub slurp_file { + my ($self, $file) = @_; + unless (open (TMPFILE, '<', $file)) { + $self->error ("cannot open temporary file $file: $!"); + return; + } + local $/; + my $data = ; + unless (close TMPFILE) { + $self->error ("cannot read temporary file $file: $!"); + return; + } + return $data; +} + ############################################################################## # Public interfaces ############################################################################## @@ -93,11 +110,38 @@ sub create { return 1; } -# Create a keytab from a principal. Takes the principal, the file, and -# optionally a list of encryption types to which to limit the keytab. Return -# true if successful, false otherwise. If the keytab creation fails, sets the -# error. +# Create a keytab for a principal. Returns the keytab as binary data or undef +# on failure, setting the error. sub keytab { + my ($self, $principal) = @_; + $principal = $self->canonicalize_principal ($principal); + my $kadmin = $self->{client}; + my $file = $Wallet::Config::KEYTAB_TMP . "/keytab.$$"; + unlink $file; + my $princdata = eval { $kadmin->getPrincipal ($principal) }; + if ($@) { + $self->error ("error creating keytab for $principal: $@"); + return; + } elsif (!$princdata) { + $self->error ("error creating keytab for $principal: principal does" + . " not exist"); + return; + } + eval { $kadmin->extractKeytab ($princdata, $file) }; + if ($@) { + $self->error ("error creating keytab for principal: $@"); + return; + } + my $data = $self->slurp_file ($file); + unlink $file; + return $data; +} + +# Create a keytab for a principal, randomizing the keys for that principal at +# the same time. Takes the principal, the file, and optionally a list of +# encryption types to which to limit the keytab. Return true if successful, +# false otherwise. If the keytab creation fails, sets the error. +sub keytab_rekey { my ($self, $principal, $file, @enctypes) = @_; $principal = $self->canonicalize_principal ($principal); @@ -213,10 +257,12 @@ Wallet::Kadmin::Heimdal - Wallet Kerberos administration API for Heimdal =head1 SYNOPSIS my $kadmin = Wallet::Kadmin::Heimdal->new; - $kadmin->create ("host/foo.example.com"); - $kadmin->keytab ("host/foo.example.com", "aes256-cts-hmac-sha1-96"); - my $exists = $kadmin->exists ("host/oldshell.example.com"); - $kadmin->destroy ("host/oldshell.example.com") if $exists; + $kadmin->create ('host/foo.example.com'); + $kadmin->keytab_rekey ('host/foo.example.com', 'keytab', + 'aes256-cts-hmac-sha1-96'); + my $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 @@ -228,6 +274,18 @@ To use this object, several configuration parameters must be set. See Wallet::Config(3) for details on those configuration parameters and information about how to set wallet configuration. +=head1 FILES + +=over 4 + +=item KEYTAB_TMP/keytab. + +The keytab is created in this file and then read into memory. KEYTAB_TMP +is set in the wallet configuration, and is the process ID of the +current process. The file is unlinked after being read. + +=back + =head1 SEE ALSO kadmin(8), Wallet::Config(3), Wallet::Kadmin(3), diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index 9ab575c..1c6d2c1 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -137,11 +137,52 @@ sub create { return 1; } -# Create a keytab from a principal. Takes the principal, the file, and -# optionally a list of encryption types to which to limit the keytab. Return -# true if successful, false otherwise. If the keytab creation fails, sets the -# error. +# 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 { + my ($self, $principal) = @_; + my $host = $Wallet::Config::KEYTAB_REMCTL_HOST; + unless ($host and $Wallet::Config::KEYTAB_REMCTL_CACHE) { + $self->error ('keytab unchanging support not configured'); + return; + } + eval { require Net::Remctl }; + if ($@) { + $self->error ("keytab unchanging support not available: $@"); + return; + } + if ($principal !~ /\@/ && $Wallet::Config::KEYTAB_REALM) { + $principal .= '@' . $Wallet::Config::KEYTAB_REALM; + } + local $ENV{KRB5CCNAME} = $Wallet::Config::KEYTAB_REMCTL_CACHE; + my $port = $Wallet::Config::KEYTAB_REMCTL_PORT || 0; + my $remctl_princ = $Wallet::Config::KEYTAB_REMCTL_PRINCIPAL || ''; + my @command = ('keytab', 'retrieve', $principal); + my $result = Net::Remctl::remctl ($host, $port, $remctl_princ, @command); + if ($result->error) { + $self->error ("cannot retrieve keytab for $principal: ", + $result->error); + return; + } elsif ($result->status != 0) { + my $error = $result->stderr; + $error =~ s/\s+$//; + $error =~ s/\n/ /g; + $self->error ("cannot retrieve keytab for $principal: $error"); + return; + } else { + return $result->stdout; + } +} + +# Create a keytab for a principal, randomizing the keys for that principal +# in the process. Takes the principal, the file, and optionally a list of +# encryption types to which to limit the keytab. Return true if +# successful, false otherwise. If the keytab creation fails, sets the +# error. +sub keytab_rekey { my ($self, $principal, $file, @enctypes) = @_; unless ($self->valid_principal ($principal)) { $self->error ("invalid principal name: $principal"); @@ -210,7 +251,7 @@ __END__ ############################################################################## =for stopwords -keytabs keytab kadmin KDC API Allbery +rekeying rekeys remctl backend keytabs keytab kadmin KDC API Allbery =head1 NAME @@ -219,10 +260,12 @@ Wallet::Kadmin::MIT - Wallet Kerberos administration API for MIT =head1 SYNOPSIS my $kadmin = Wallet::Kadmin::MIT->new; - $kadmin->create ("host/foo.example.com"); - $kadmin->keytab ("host/foo.example.com", "aes256-cts-hmac-sha1-96"); - my $exists = $kadmin->exists ("host/oldshell.example.com"); - $kadmin->destroy ("host/oldshell.example.com") if $exists; + $kadmin->create ('host/foo.example.com'); + $kadmin->keytab_rekey ('host/foo.example.com', 'keytab', + 'aes256-cts-hmac-sha1-96'); + my $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 @@ -231,6 +274,13 @@ providing an interface to create and delete principals and create keytabs. It provides the API documented in Wallet::Kadmin(3) for an MIT Kerberos KDC. +MIT Kerberos does not provide any method via the kadmin network protocol +to retrieve a keytab for a principal without rekeying it, so the keytab() +method (as opposed to keytab_rekey(), which rekeys the principal) is +implemented using a remctl backend. For that method (used for unchanging +keytab objects) to work, the necessary wallet configuration and remctl +interface on the KDC must be set up. + To use this object, several configuration parameters must be set. See Wallet::Config(3) for details on those configuration parameters and information about how to set wallet configuration. diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index 44ee003..5c66967 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -179,49 +179,6 @@ sub sync_list { return @targets; } -############################################################################## -# 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_REMCTL_CACHE) { - $self->error ('keytab unchanging support not configured'); - return; - } - eval { require Net::Remctl }; - if ($@) { - $self->error ("keytab unchanging support not available: $@"); - return; - } - if ($Wallet::Config::KEYTAB_REALM) { - $keytab .= '@' . $Wallet::Config::KEYTAB_REALM; - } - local $ENV{KRB5CCNAME} = $Wallet::Config::KEYTAB_REMCTL_CACHE; - my $port = $Wallet::Config::KEYTAB_REMCTL_PORT || 0; - 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; - } elsif ($result->status != 0) { - my $error = $result->stderr; - $error =~ s/\s+$//; - $error =~ s/\n/ /g; - $self->error ("cannot retrieve keytab for $keytab: $error"); - return; - } else { - return $result->stdout; - } -} - ############################################################################## # Core methods ############################################################################## @@ -365,8 +322,9 @@ sub get { $self->error ("cannot get $id: object is locked"); return; } + my $kadmin = $self->{kadmin}; if ($self->flag_check ('unchanging')) { - my $result = $self->keytab_retrieve ($self->{name}); + my $result = $kadmin->keytab ($self->{name}); if (defined $result) { $self->log_action ('get', $user, $host, $time); } @@ -379,8 +337,7 @@ sub get { my $file = $Wallet::Config::KEYTAB_TMP . "/keytab.$$"; unlink $file; my @enctypes = $self->attr ('enctypes'); - my $kadmin = $self->{kadmin}; - if (not $kadmin->keytab ($self->{name}, $file, @enctypes)) { + if (not $kadmin->keytab_rekey ($self->{name}, $file, @enctypes)) { $self->error ($kadmin->error); return; } diff --git a/perl/t/kadmin.t b/perl/t/kadmin.t index 9c49995..a29cae3 100755 --- a/perl/t/kadmin.t +++ b/perl/t/kadmin.t @@ -91,7 +91,7 @@ SKIP: { is ($kadmin->create ('wallet/one'), 1, 'Creating wallet/one works'); is ($kadmin->exists ('wallet/one'), 1, ' and it now exists'); unlink ('./tmp.keytab'); - is ($kadmin->keytab ('wallet/one', './tmp.keytab'), 1, + is ($kadmin->keytab_rekey ('wallet/one', './tmp.keytab'), 1, ' and retrieving a keytab works'); ok (-s './tmp.keytab', ' and the resulting keytab is non-zero'); is (getcreds ('./tmp.keytab', "wallet/one\@$Wallet::Config::KEYTAB_REALM"), @@ -101,7 +101,7 @@ SKIP: { # Delete the principal and confirm behavior. is ($kadmin->destroy ('wallet/one'), 1, 'Deleting principal works'); is ($kadmin->exists ('wallet/one'), 0, ' and now it does not exist'); - is ($kadmin->keytab ('wallet/one', './tmp.keytab'), undef, + is ($kadmin->keytab_rekey ('wallet/one', './tmp.keytab'), undef, ' and retrieving the keytab does not work'); ok (! -f './tmp.keytab', ' and no file was created'); like ($kadmin->error, qr%^error creating keytab for wallet/one%, diff --git a/perl/t/keytab.t b/perl/t/keytab.t index a14b63e..a702c0f 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -9,7 +9,7 @@ # See LICENSE for licensing terms. use POSIX qw(strftime); -use Test::More tests => 125; +use Test::More tests => 135; use Wallet::Admin; use Wallet::Config; @@ -378,12 +378,7 @@ EOO # Tests for unchanging support. Skip these if we don't have a keytab or if we # can't find remctld. SKIP: { - skip 'no keytab configuration', 17 unless -f 't/data/test.keytab'; - my @path = (split (':', $ENV{PATH}), '/usr/local/sbin', '/usr/sbin'); - my ($remctld) = grep { -x $_ } map { "$_/remctld" } @path; - skip 'remctld not found', 17 unless $remctld; - eval { require Net::Remctl }; - skip 'Net::Remctl not available', 17 if $@; + skip 'no keytab configuration', 27 unless -f 't/data/test.keytab'; # Set up our configuration. $Wallet::Config::KEYTAB_FILE = 't/data/test.keytab'; @@ -406,41 +401,85 @@ SKIP: { ok (defined ($two), 'Creating wallet/two succeeds'); is ($two->flag_set ('unchanging', @trace), 1, ' and setting unchanging'); - # Now spawn our remctld server and get a ticket cache. - remctld_spawn ($remctld, $principal, 't/data/test.keytab', - 't/data/keytab.conf'); - $ENV{KRB5CCNAME} = 'krb5cc_test'; - getcreds ('t/data/test.keytab', $principal); - $ENV{KRB5CCNAME} = 'krb5cc_good'; + # Finally we can test. First the MIT Kerberos tests. + SKIP: { + skip 'skipping MIT unchanging tests for Heimdal', 12 + if (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'heimdal'); + + # We need remctld and Net::Remctl. + my @path = (split (':', $ENV{PATH}), '/usr/local/sbin', '/usr/sbin'); + my ($remctld) = grep { -x $_ } map { "$_/remctld" } @path; + skip 'remctld not found', 12 unless $remctld; + eval { require Net::Remctl }; + skip 'Net::Remctl not available', 12 if $@; + + # Now spawn our remctld server and get a ticket cache. + remctld_spawn ($remctld, $principal, 't/data/test.keytab', + 't/data/keytab.conf'); + $ENV{KRB5CCNAME} = 'krb5cc_test'; + getcreds ('t/data/test.keytab', $principal); + $ENV{KRB5CCNAME} = 'krb5cc_good'; + + # Do the unchanging tests for MIT Kerberos. + is ($one->get (@trace), undef, 'Get without configuration fails'); + is ($one->error, 'keytab unchanging support not configured', + ' with the right error'); + $Wallet::Config::KEYTAB_REMCTL_CACHE = 'krb5cc_test'; + is ($one->get (@trace), undef, ' and still fails without host'); + is ($one->error, 'keytab unchanging support not configured', + ' with the right error'); + $Wallet::Config::KEYTAB_REMCTL_HOST = 'localhost'; + $Wallet::Config::KEYTAB_REMCTL_PRINCIPAL = $principal; + $Wallet::Config::KEYTAB_REMCTL_PORT = 14373; + is ($one->get (@trace), undef, ' and still fails without ACL'); + is ($one->error, + "cannot retrieve keytab for wallet/one\@$realm: Access denied", + ' with the right error'); + open (ACL, '>', 'test-acl') or die "cannot create test-acl: $!\n"; + print ACL "$principal\n"; + close ACL; + is ($one->get (@trace), 'Keytab for wallet/one', 'Now get works'); + is ($ENV{KRB5CCNAME}, 'krb5cc_good', + ' and we did not nuke the cache name'); + is ($one->get (@trace), 'Keytab for wallet/one', + ' and we get the same thing the second time'); + is ($one->flag_clear ('unchanging', @trace), 1, + 'Clearing the unchanging flag works'); + my $data = $object->get (@trace); + ok (defined ($data), ' and getting the keytab works'); + ok (valid ($data, 'wallet/one'), ' and the keytab is valid'); + is ($two->get (@trace), undef, 'Get for wallet/two does not work'); + is ($two->error, + "cannot retrieve keytab for wallet/two\@$realm: bite me", + ' with the right error'); + is ($one->destroy (@trace), 1, 'Destroying wallet/one works'); + is ($two->destroy (@trace), 1, ' as does destroying wallet/two'); + remctld_stop; + } - # Finally we can test. - is ($one->get (@trace), undef, 'Get without configuration fails'); - is ($one->error, 'keytab unchanging support not configured', - ' with the right error'); - $Wallet::Config::KEYTAB_REMCTL_CACHE = 'krb5cc_test'; - is ($one->get (@trace), undef, ' and still fails without host'); - is ($one->error, 'keytab unchanging support not configured', - ' with the right error'); - $Wallet::Config::KEYTAB_REMCTL_HOST = 'localhost'; - $Wallet::Config::KEYTAB_REMCTL_PRINCIPAL = $principal; - $Wallet::Config::KEYTAB_REMCTL_PORT = 14373; - is ($one->get (@trace), undef, ' and still fails without ACL'); - is ($one->error, - "cannot retrieve keytab for wallet/one\@$realm: Access denied", - ' with the right error'); - open (ACL, '>', 'test-acl') or die "cannot create test-acl: $!\n"; - print ACL "$principal\n"; - close ACL; - is ($one->get (@trace), 'Keytab for wallet/one', 'Now get works'); - is ($ENV{KRB5CCNAME}, 'krb5cc_good', - ' and we did not nuke the cache name'); - is ($two->get (@trace), undef, ' but get for wallet/two does not'); - is ($two->error, - "cannot retrieve keytab for wallet/two\@$realm: bite me", - ' with the right error'); - is ($one->destroy (@trace), 1, 'Destroying wallet/one works'); - is ($two->destroy (@trace), 1, ' as does destroying wallet/two'); - remctld_stop; + # Now Heimdal. Since the keytab contains timestamps, before testing for + # equality we have to substitute out the timestamps. + SKIP: { + skip 'skipping Heimdal unchanging tests for MIT', 10 + if (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'mit'); + my $data = $one->get (@trace); + ok (defined $data, 'Get of unchanging keytab works'); + ok (valid ($data, 'wallet/one'), ' and the keytab is valid'); + my $second = $one->get (@trace); + ok (defined $second, ' and second retrieval also works'); + $data =~ s/one.{8}/one\000\000\000\000\000\000\000\000/g; + $second =~ s/one.{8}/one\000\000\000\000\000\000\000\000/g; + is ($data, $second, ' and the keytab matches'); + is ($one->flag_clear ('unchanging', @trace), 1, + 'Clearing the unchanging flag works'); + $data = $one->get (@trace); + ok (defined ($data), ' and getting the keytab works'); + ok (valid ($data, 'wallet/one'), ' and the keytab is valid'); + $data =~ s/one.{8}/one\000\000\000\000\000\000\000\000/g; + ok ($data ne $second, ' and the new keytab is different'); + is ($one->destroy (@trace), 1, 'Destroying wallet/one works'); + is ($two->destroy (@trace), 1, ' as does destroying wallet/two'); + } # Check that history has been updated correctly. $history .= <<"EOO"; @@ -450,6 +489,12 @@ $date set flag unchanging by $user from $host $date get by $user from $host +$date get + by $user from $host +$date clear flag unchanging + by $user from $host +$date get + by $user from $host $date destroy by $user from $host EOO -- cgit v1.2.3 From 93eb5f8fe8d05398dd6fb364680e40eb8dae23e4 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Thu, 18 Feb 2010 22:06:17 -0800 Subject: Refactor Wallet::Kadmin keytab_rekey to return keytab Change the API for keytab_rekey to match keytab, returning the keytab as data instead of writing it to a file. This simplifies the wallet object implementation and moves the logic for reading the temporary file into Wallet::Kadmin and its child classes. (Eventually, there may be a kadmin backend that doesn't require using a temporary file.) Setting KEYTAB_TMP is now required to instantiate either the ::MIT or ::Heimdal Wallet::Kadmin classes. --- perl/Wallet/Kadmin.pm | 54 ++++++++++++++++++++++++++++++++++++------- perl/Wallet/Kadmin/Heimdal.pm | 41 +++++++++++--------------------- perl/Wallet/Kadmin/MIT.pm | 39 +++++++++++++++++++++---------- perl/Wallet/Object/Keytab.pm | 42 ++++++++------------------------- perl/t/kadmin.t | 15 ++++++------ perl/t/keytab.t | 42 +++++++++++++-------------------- perl/t/lib/Util.pm | 21 +++++++++++++++-- 7 files changed, 137 insertions(+), 117 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index f3c2895..074dd1e 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -22,6 +22,33 @@ use Wallet::Config (); # 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 = ; + if ($!) { + $self->error ("cannot read temporary file $file: $!"); + unlink $file; + return; + } + close TMPFILE; + unlink $file; + return $data; +} + ############################################################################## # Public methods ############################################################################## @@ -84,9 +111,9 @@ Wallet::Kadmin - Kerberos administration API for wallet keytab backend my $kadmin = Wallet::Kadmin->new; $kadmin->create ('host/foo.example.com'); - $kadmin->keytab_rekey ('host/foo.example.com', 'keytab', - 'aes256-cts-hmac-sha1-96'); - my $data = $kadmin->keytab ('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; @@ -101,9 +128,8 @@ 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. -To use this object, several configuration parameters must be set. See -Wallet::Config(3) for details on those configuration parameters and -information about how to set wallet configuration. +See L for details on how to +configure this module. =head1 CLASS METHODS @@ -174,7 +200,7 @@ 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, FILE [, ENCTYPE ...]) +=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 @@ -183,7 +209,19 @@ 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 or C). If none are given, the KDC defaults will be used. -Returns true on success and false on failure. +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 diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index e066006..d1eecda 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -39,23 +39,6 @@ sub canonicalize_principal { return $principal; } -# Read the entirety of a possibly binary file and return the contents. If -# reading the file fails, set the error message and return undef. -sub slurp_file { - my ($self, $file) = @_; - unless (open (TMPFILE, '<', $file)) { - $self->error ("cannot open temporary file $file: $!"); - return; - } - local $/; - my $data = ; - unless (close TMPFILE) { - $self->error ("cannot read temporary file $file: $!"); - return; - } - return $data; -} - ############################################################################## # Public interfaces ############################################################################## @@ -132,17 +115,15 @@ sub keytab { $self->error ("error creating keytab for principal: $@"); return; } - my $data = $self->slurp_file ($file); - unlink $file; - return $data; + return $self->read_keytab ($file); } # Create a keytab for a principal, randomizing the keys for that principal at -# the same time. Takes the principal, the file, and optionally a list of -# encryption types to which to limit the keytab. Return true if successful, -# false otherwise. If the keytab creation fails, sets the error. +# the same time. Takes the principal and an optional list of encryption types +# to which to limit the keytab. Return the keytab data on success and undef +# on failure. If the keytab creation fails, sets the error. sub keytab_rekey { - my ($self, $principal, $file, @enctypes) = @_; + my ($self, $principal, @enctypes) = @_; $principal = $self->canonicalize_principal ($principal); # The way Heimdal works, you can only remove enctypes from a principal, @@ -188,12 +169,14 @@ sub keytab_rekey { } # Create the keytab. + my $file = $Wallet::Config::KEYTAB_TMP . "/keytab.$$"; + unlink $file; eval { $kadmin->extractKeytab ($princdata, $file) }; if ($@) { $self->error ("error creating keytab for principal: $@"); return; } - return 1; + return $self->read_keytab ($file); } # Delete a principal from Kerberos. Return true if successful, false @@ -227,6 +210,9 @@ sub new { and defined ($Wallet::Config::KEYTAB_REALM)) { die "keytab object implementation not configured\n"; } + unless (defined ($Wallet::Config::KEYTAB_TMP)) { + die "KEYTAB_TMP configuration variable not set\n"; + } my @options = (RaiseError => 1, Principal => $Wallet::Config::KEYTAB_PRINCIPAL, Realm => $Wallet::Config::KEYTAB_REALM, @@ -270,9 +256,8 @@ Wallet::Kadmin::Heimdal implements the Wallet::Kadmin API for Heimdal, providing an interface to create and delete principals and create keytabs. It provides the API documented in Wallet::Kadmin(3) for a Heimdal KDC. -To use this object, several configuration parameters must be set. See -Wallet::Config(3) for details on those configuration parameters and -information about how to set wallet configuration. +To use this class, several configuration parameters must be set. See +L for details. =head1 FILES diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index 1c6d2c1..434e93d 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -178,12 +178,11 @@ sub keytab { } # Create a keytab for a principal, randomizing the keys for that principal -# in the process. Takes the principal, the file, and optionally a list of -# encryption types to which to limit the keytab. Return true if -# successful, false otherwise. If the keytab creation fails, sets the -# error. +# in the process. Takes the principal and an optional list of encryption +# types to which to limit the keytab. Return the keytab data on success +# and undef otherwise. If the keytab creation fails, sets the error. sub keytab_rekey { - my ($self, $principal, $file, @enctypes) = @_; + my ($self, $principal, @enctypes) = @_; unless ($self->valid_principal ($principal)) { $self->error ("invalid principal name: $principal"); return; @@ -191,6 +190,8 @@ sub keytab_rekey { if ($Wallet::Config::KEYTAB_REALM) { $principal .= '@' . $Wallet::Config::KEYTAB_REALM; } + my $file = $Wallet::Config::KEYTAB_TMP . "/keytab.$$"; + unlink $file; my $command = "ktadd -q -k $file"; if (@enctypes) { @enctypes = map { /:/ ? $_ : "$_:normal" } @enctypes; @@ -203,7 +204,7 @@ sub keytab_rekey { $self->error ("error creating keytab for $principal: $1"); return; } - return 1; + return $self->read_keytab ($file); } # Delete a principal from Kerberos. Return true if successful, false @@ -238,6 +239,9 @@ sub destroy { # kadmin directly. sub new { my ($class) = @_; + unless (defined ($Wallet::Config::KEYTAB_TMP)) { + die "KEYTAB_TMP configuration variable not set\n"; + } my $self = {}; bless ($self, $class); return $self; @@ -261,9 +265,9 @@ Wallet::Kadmin::MIT - Wallet Kerberos administration API for MIT my $kadmin = Wallet::Kadmin::MIT->new; $kadmin->create ('host/foo.example.com'); - $kadmin->keytab_rekey ('host/foo.example.com', 'keytab', - 'aes256-cts-hmac-sha1-96'); - my $data = $kadmin->keytab ('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; @@ -281,9 +285,20 @@ implemented using a remctl backend. For that method (used for unchanging keytab objects) to work, the necessary wallet configuration and remctl interface on the KDC must be set up. -To use this object, several configuration parameters must be set. See -Wallet::Config(3) for details on those configuration parameters and -information about how to set wallet configuration. +To use this class, several configuration parameters must be set. See +L for details. + +=head1 FILES + +=over 4 + +=item KEYTAB_TMP/keytab. + +The keytab is created in this file and then read into memory. KEYTAB_TMP +is set in the wallet configuration, and is the process ID of the +current process. The file is unlinked after being read. + +=back =head1 LIMITATIONS diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index 5c66967..edb26b3 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -323,43 +323,19 @@ sub get { return; } my $kadmin = $self->{kadmin}; + my $result; if ($self->flag_check ('unchanging')) { - my $result = $kadmin->keytab ($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; + $result = $kadmin->keytab ($self->{name}); + } else { + my @enctypes = $self->attr ('enctypes'); + $result = $kadmin->keytab_rekey ($self->{name}, @enctypes); } - my $file = $Wallet::Config::KEYTAB_TMP . "/keytab.$$"; - unlink $file; - my @enctypes = $self->attr ('enctypes'); - if (not $kadmin->keytab_rekey ($self->{name}, $file, @enctypes)) { + if (defined $result) { + $self->log_action ('get', $user, $host, $time); + } else { $self->error ($kadmin->error); - return; - } - local *KEYTAB; - unless (open (KEYTAB, '<', $file)) { - my $princ = $self->{name}; - $self->error ("error opening keytab for principal $princ: $!"); - return; - } - local $/; - undef $!; - my $data = ; - if ($!) { - my $princ = $self->{name}; - $self->error ("error reading keytab for principal $princ: $!"); - unlink $file; - return; } - close KEYTAB; - unlink $file; - $self->log_action ('get', $user, $host, $time); - return $data; + return $result; } 1; diff --git a/perl/t/kadmin.t b/perl/t/kadmin.t index a29cae3..b9ac769 100755 --- a/perl/t/kadmin.t +++ b/perl/t/kadmin.t @@ -8,7 +8,9 @@ # See LICENSE for licensing terms. use POSIX qw(strftime); -use Test::More tests => 33; +use Test::More tests => 32; + +BEGIN { $Wallet::Config::KEYTAB_TMP = '.' } use Wallet::Admin; use Wallet::Config; @@ -90,13 +92,10 @@ SKIP: { # check the details of the return in the keytab check. is ($kadmin->create ('wallet/one'), 1, 'Creating wallet/one works'); is ($kadmin->exists ('wallet/one'), 1, ' and it now exists'); - unlink ('./tmp.keytab'); - is ($kadmin->keytab_rekey ('wallet/one', './tmp.keytab'), 1, - ' and retrieving a keytab works'); - ok (-s './tmp.keytab', ' and the resulting keytab is non-zero'); - is (getcreds ('./tmp.keytab', "wallet/one\@$Wallet::Config::KEYTAB_REALM"), - 1, ' and works for authentication'); - unlink ('./tmp.keytab'); + my $data = $kadmin->keytab_rekey ('wallet/one'); + ok (defined ($data), ' and retrieving a keytab works'); + is (keytab_valid ($data, 'wallet/one'), 1, + ' and works for authentication'); # Delete the principal and confirm behavior. is ($kadmin->destroy ('wallet/one'), 1, 'Deleting principal works'); diff --git a/perl/t/keytab.t b/perl/t/keytab.t index a702c0f..4e253eb 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -11,6 +11,8 @@ use POSIX qw(strftime); use Test::More tests => 135; +BEGIN { $Wallet::Config::KEYTAB_TMP = '.' } + use Wallet::Admin; use Wallet::Config; use Wallet::Kadmin; @@ -89,21 +91,6 @@ sub created { } } -# Given keytab data and the principal, write it to a file and try -# authenticating using kinit. -sub valid { - my ($keytab, $principal) = @_; - open (KEYTAB, '>', 'keytab') or die "cannot create keytab: $!\n"; - print KEYTAB $keytab; - close KEYTAB; - $principal .= '@' . $Wallet::Config::KEYTAB_REALM; - my $result = getcreds ('keytab', $principal); - if ($result) { - unlink 'keytab'; - } - return $result; -} - # Given keytab data, write it to a file and try to determine the enctypes of # the keys present in that file. Returns the enctypes as a list, with UNKNOWN # for encryption types that weren't recognized. This is an ugly way of doing @@ -168,7 +155,6 @@ SKIP: { $Wallet::Config::KEYTAB_PRINCIPAL = contents ('t/data/test.principal'); $Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm'); $Wallet::Config::KEYTAB_KRBTYPE = contents ('t/data/test.krbtype'); - $Wallet::Config::KEYTAB_TMP = '.'; my $realm = $Wallet::Config::KEYTAB_REALM; # Clean up the principals we're going to use. @@ -178,6 +164,16 @@ SKIP: { # Don't destroy the user's Kerberos ticket cache. $ENV{KRB5CCNAME} = 'krb5cc_test'; + # Test that object creation without KEYTAB_TMP fails. + undef $Wallet::Config::KEYTAB_TMP; + $object = eval { + Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace) + }; + is ($object, undef, 'Creating keytab without KEYTAB_TMP fails'); + is ($@, "KEYTAB_TMP configuration variable not set\n", + ' with the right error'); + $Wallet::Config::KEYTAB_TMP = '.'; + # Okay, now we can test. First, create. $object = eval { Wallet::Object::Keytab->create ('keytab', "wallet\nf", $dbh, @trace) @@ -244,7 +240,7 @@ SKIP: { is ($object->error, '', ' and getting the keytab works'); } ok (! -f "./keytab.$$", ' and the temporary file was cleaned up'); - ok (valid ($data, 'wallet/one'), ' and the keytab is valid'); + ok (keytab_valid ($data, 'wallet/one'), ' and the keytab is valid'); # For right now, this is the only backend type that we have for which we # can do a get, so test display of the last download information. @@ -261,12 +257,6 @@ EOO is ($object->show, $expected, 'Show output is correct'); # Test error handling on keytab retrieval. - undef $Wallet::Config::KEYTAB_TMP; - $data = $object->get (@trace); - is ($data, undef, 'Getting a keytab without a tmp directory fails'); - is ($object->error, 'KEYTAB_TMP configuration variable not set', - ' with the right error'); - $Wallet::Config::KEYTAB_TMP = '.'; SKIP: { skip 'no kadmin program test for Heimdal', 2 if $Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal'; @@ -447,7 +437,7 @@ SKIP: { 'Clearing the unchanging flag works'); my $data = $object->get (@trace); ok (defined ($data), ' and getting the keytab works'); - ok (valid ($data, 'wallet/one'), ' and the keytab is valid'); + ok (keytab_valid ($data, 'wallet/one'), ' and the keytab is valid'); is ($two->get (@trace), undef, 'Get for wallet/two does not work'); is ($two->error, "cannot retrieve keytab for wallet/two\@$realm: bite me", @@ -464,7 +454,7 @@ SKIP: { if (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'mit'); my $data = $one->get (@trace); ok (defined $data, 'Get of unchanging keytab works'); - ok (valid ($data, 'wallet/one'), ' and the keytab is valid'); + ok (keytab_valid ($data, 'wallet/one'), ' and the keytab is valid'); my $second = $one->get (@trace); ok (defined $second, ' and second retrieval also works'); $data =~ s/one.{8}/one\000\000\000\000\000\000\000\000/g; @@ -474,7 +464,7 @@ SKIP: { 'Clearing the unchanging flag works'); $data = $one->get (@trace); ok (defined ($data), ' and getting the keytab works'); - ok (valid ($data, 'wallet/one'), ' and the keytab is valid'); + ok (keytab_valid ($data, 'wallet/one'), ' and the keytab is valid'); $data =~ s/one.{8}/one\000\000\000\000\000\000\000\000/g; ok ($data ne $second, ' and the new keytab is different'); is ($one->destroy (@trace), 1, 'Destroying wallet/one works'); diff --git a/perl/t/lib/Util.pm b/perl/t/lib/Util.pm index ac0f530..ab88b39 100644 --- a/perl/t/lib/Util.pm +++ b/perl/t/lib/Util.pm @@ -20,7 +20,8 @@ $VERSION = '0.02'; use Exporter (); @ISA = qw(Exporter); -@EXPORT = qw(contents db_setup getcreds remctld_spawn remctld_stop); +@EXPORT = qw(contents db_setup getcreds keytab_valid remctld_spawn + remctld_stop); ############################################################################## # General utility functions @@ -66,7 +67,7 @@ sub db_setup { } ############################################################################## -# Local ticket cache +# Kerberos utility functions ############################################################################## # Given a keytab file and a principal, try authenticating with kinit. @@ -85,6 +86,22 @@ sub getcreds { return 0; } +# Given keytab data and the principal, write it to a file and try +# authenticating using kinit. +sub keytab_valid { + my ($keytab, $principal) = @_; + open (KEYTAB, '>', 'keytab') or die "cannot create keytab: $!\n"; + print KEYTAB $keytab; + close KEYTAB; + $principal .= '@' . $Wallet::Config::KEYTAB_REALM + unless $principal =~ /\@/; + my $result = getcreds ('keytab', $principal); + if ($result) { + unlink 'keytab'; + } + return $result; +} + ############################################################################## # remctld handling ############################################################################## -- cgit v1.2.3 From 4d11772001f65264bf714711550acdbb05900f4c Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Wed, 27 Feb 2013 14:46:47 -0800 Subject: Use correct form of Stanford's copyright statement Change-Id: I06dd9ecca19315179bdd34d4b301548fe7604331 Reviewed-on: https://gerrit.stanford.edu/842 Reviewed-by: Russ Allbery Tested-by: Russ Allbery --- client/file.c | 3 ++- client/internal.h | 3 ++- client/keytab.c | 3 ++- client/krb5.c | 3 ++- client/options.c | 2 +- client/remctl.c | 3 ++- client/srvtab.c | 3 ++- client/wallet-rekey.c | 3 ++- client/wallet.c | 2 +- configure.ac | 4 +--- contrib/convert-srvtab-db | 3 ++- contrib/used-principals | 3 ++- contrib/wallet-contacts | 3 ++- contrib/wallet-summary | 3 ++- contrib/wallet-unknown-hosts | 3 ++- examples/stanford.conf | 3 ++- perl/Wallet/ACL.pm | 3 ++- perl/Wallet/ACL/Base.pm | 3 ++- perl/Wallet/ACL/Krb5.pm | 3 ++- perl/Wallet/ACL/Krb5/Regex.pm | 3 ++- perl/Wallet/ACL/NetDB.pm | 3 ++- perl/Wallet/ACL/NetDB/Root.pm | 3 ++- perl/Wallet/Config.pm | 3 ++- perl/Wallet/Database.pm | 3 ++- perl/Wallet/Kadmin.pm | 3 ++- perl/Wallet/Kadmin/Heimdal.pm | 3 ++- perl/Wallet/Kadmin/MIT.pm | 2 +- perl/Wallet/Object/File.pm | 3 ++- perl/Wallet/Object/Keytab.pm | 4 ++-- perl/Wallet/Report.pm | 3 ++- perl/create-ddl | 3 ++- perl/t/acl.t | 3 ++- perl/t/config.t | 3 ++- perl/t/file.t | 3 ++- perl/t/init.t | 3 ++- perl/t/keytab.t | 2 +- perl/t/lib/Util.pm | 3 ++- perl/t/pod.t | 3 ++- perl/t/report.t | 3 ++- perl/t/verifier-netdb.t | 3 ++- perl/t/verifier.t | 3 ++- server/keytab-backend | 2 +- server/wallet-report | 3 ++- tests/client/basic-t.in | 2 +- tests/client/full-t.in | 3 ++- tests/client/prompt-t.in | 3 ++- tests/client/rekey-t.in | 2 +- tests/data/cmd-fake | 4 +++- tests/data/fake-kadmin | 3 ++- tests/server/keytab-t | 3 ++- tests/server/report-t | 3 ++- 51 files changed, 95 insertions(+), 54 deletions(-) (limited to 'perl/Wallet/Kadmin.pm') diff --git a/client/file.c b/client/file.c index 861da6a..c171969 100644 --- a/client/file.c +++ b/client/file.c @@ -2,7 +2,8 @@ * File handling for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/internal.h b/client/internal.h index c8e5802..24dd875 100644 --- a/client/internal.h +++ b/client/internal.h @@ -2,7 +2,8 @@ * Internal support functions for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/keytab.c b/client/keytab.c index 6614c4b..0a3e419 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -2,7 +2,8 @@ * Implementation of keytab handling for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010, 2013 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/krb5.c b/client/krb5.c index aad39f6..e86a225 100644 --- a/client/krb5.c +++ b/client/krb5.c @@ -6,7 +6,8 @@ * client. * * Written by Russ Allbery - * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 + * The Board of Trustees of the Leland Stanford Junior University */ #include diff --git a/client/options.c b/client/options.c index 2f1de70..67ecb7f 100644 --- a/client/options.c +++ b/client/options.c @@ -6,7 +6,7 @@ * * Written by Russ Allbery * Copyright 2006, 2007, 2008, 2010 - * Board of Trustees, Leland Stanford Jr. University + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/remctl.c b/client/remctl.c index 5a541d5..071e410 100644 --- a/client/remctl.c +++ b/client/remctl.c @@ -2,7 +2,8 @@ * remctl interface for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2010 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/srvtab.c b/client/srvtab.c index b26e6fc..73277e9 100644 --- a/client/srvtab.c +++ b/client/srvtab.c @@ -2,7 +2,8 @@ * Implementation of srvtab handling for the wallet client. * * Written by Russ Allbery - * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2007, 2008, 2010 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/wallet-rekey.c b/client/wallet-rekey.c index 3a9687c..5007f41 100644 --- a/client/wallet-rekey.c +++ b/client/wallet-rekey.c @@ -3,7 +3,8 @@ * * Written by Russ Allbery * and Jon Robertson - * Copyright 2010 Board of Trustees, Leland Stanford Jr. University + * Copyright 2010 + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/client/wallet.c b/client/wallet.c index dc04dcd..c5a7877 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -3,7 +3,7 @@ * * Written by Russ Allbery * Copyright 2006, 2007, 2008, 2010 - * Board of Trustees, Leland Stanford Jr. University + * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. */ diff --git a/configure.ac b/configure.ac index a79e42d..4fc218b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,12 +2,10 @@ dnl Autoconf configuration for wallet. dnl dnl Written by Russ Allbery dnl Copyright 2006, 2007, 2008, 2010 -dnl Board of Trustees, Leland Stanford Jr. University +dnl The Board of Trustees of the Leland Stanford Junior University dnl dnl See LICENSE for licensing terms. -dnl We cannot use -Wall -Werror with AM_INIT_AUTOMAKE since we override -dnl distuninstallcheck (not supported by Perl). AC_PREREQ([2.64]) AC_INIT([wallet], [0.12], [rra@stanford.edu]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/contrib/convert-srvtab-db b/contrib/convert-srvtab-db index 8d3b31e..6263472 100755 --- a/contrib/convert-srvtab-db +++ b/contrib/convert-srvtab-db @@ -3,7 +3,8 @@ # convert-srvtab-db -- Converts a leland_srvtab database to wallet # # Written by Russ Allbery -# Copyright 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/contrib/used-principals b/contrib/used-principals index aa838fe..ca431e3 100755 --- a/contrib/used-principals +++ b/contrib/used-principals @@ -3,7 +3,8 @@ # used-principals -- Report which Kerberos v5 principals are in use. # # Written by Russ Allbery -# Copyright 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/contrib/wallet-contacts b/contrib/wallet-contacts index 177fc76..907c161 100755 --- a/contrib/wallet-contacts +++ b/contrib/wallet-contacts @@ -3,7 +3,8 @@ # wallet-contacts -- Report contact addresses for matching wallet objects. # # Written by Russ Allbery -# Copyright 2009 Board of Trustees, Leland Stanford Jr. University +# Copyright 2009 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/contrib/wallet-summary b/contrib/wallet-summary index aba8406..2237351 100755 --- a/contrib/wallet-summary +++ b/contrib/wallet-summary @@ -3,7 +3,8 @@ # wallet-summary -- Summarize keytabs in the wallet database. # # Written by Russ Allbery -# Copyright 2003, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2003, 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/contrib/wallet-unknown-hosts b/contrib/wallet-unknown-hosts index da972b2..e19dcf0 100755 --- a/contrib/wallet-unknown-hosts +++ b/contrib/wallet-unknown-hosts @@ -3,7 +3,8 @@ # wallet-unknown-hosts -- Report host keytabs in wallet for unknown hosts. # # Written by Russ Allbery -# Copyright 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/examples/stanford.conf b/examples/stanford.conf index becfc6e..1d14796 100644 --- a/examples/stanford.conf +++ b/examples/stanford.conf @@ -6,7 +6,8 @@ # ACL rules. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL.pm b/perl/Wallet/ACL.pm index 1e62e7b..5d9e8f2 100644 --- a/perl/Wallet/ACL.pm +++ b/perl/Wallet/ACL.pm @@ -1,7 +1,8 @@ # Wallet::ACL -- Implementation of ACLs in the wallet system. # # Written by Russ Allbery -# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010, 2013 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL/Base.pm b/perl/Wallet/ACL/Base.pm index 85eaefa..5112c2f 100644 --- a/perl/Wallet/ACL/Base.pm +++ b/perl/Wallet/ACL/Base.pm @@ -1,7 +1,8 @@ # Wallet::ACL::Base -- Parent class for wallet ACL verifiers. # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL/Krb5.pm b/perl/Wallet/ACL/Krb5.pm index 12be141..716a223 100644 --- a/perl/Wallet/ACL/Krb5.pm +++ b/perl/Wallet/ACL/Krb5.pm @@ -1,7 +1,8 @@ # Wallet::ACL::Krb5 -- Wallet Kerberos v5 principal ACL verifier. # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL/Krb5/Regex.pm b/perl/Wallet/ACL/Krb5/Regex.pm index 8f9702e..ce2fe48 100644 --- a/perl/Wallet/ACL/Krb5/Regex.pm +++ b/perl/Wallet/ACL/Krb5/Regex.pm @@ -1,7 +1,8 @@ # Wallet::ACL::Krb5::Regex -- Wallet Kerberos v5 principal regex ACL verifier # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL/NetDB.pm b/perl/Wallet/ACL/NetDB.pm index 0aa8958..2d35f49 100644 --- a/perl/Wallet/ACL/NetDB.pm +++ b/perl/Wallet/ACL/NetDB.pm @@ -1,7 +1,8 @@ # Wallet::ACL::NetDB -- Wallet NetDB role ACL verifier. # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/ACL/NetDB/Root.pm b/perl/Wallet/ACL/NetDB/Root.pm index c28bb1e..ea79d79 100644 --- a/perl/Wallet/ACL/NetDB/Root.pm +++ b/perl/Wallet/ACL/NetDB/Root.pm @@ -1,7 +1,8 @@ # Wallet::ACL::NetDB::Root -- Wallet NetDB role ACL verifier (root instances). # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Config.pm b/perl/Wallet/Config.pm index 9649c6c..af153e7 100644 --- a/perl/Wallet/Config.pm +++ b/perl/Wallet/Config.pm @@ -1,7 +1,8 @@ # Wallet::Config -- Configuration handling for the wallet server. # # Written by Russ Allbery -# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010, 2013 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Database.pm b/perl/Wallet/Database.pm index 8df338a..61de0ba 100644 --- a/perl/Wallet/Database.pm +++ b/perl/Wallet/Database.pm @@ -6,7 +6,8 @@ # like DBIx::Class objects in the rest of the code. # # Written by Russ Allbery -# Copyright 2008-2012 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010, 2012, 2013 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm index 074dd1e..bfff3ef 100644 --- a/perl/Wallet/Kadmin.pm +++ b/perl/Wallet/Kadmin.pm @@ -1,7 +1,8 @@ # Wallet::Kadmin -- Kerberos administration API for wallet keytab backend. # # Written by Jon Robertson -# Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2009, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm index 6c91b1d..bb07b93 100644 --- a/perl/Wallet/Kadmin/Heimdal.pm +++ b/perl/Wallet/Kadmin/Heimdal.pm @@ -1,7 +1,8 @@ # Wallet::Kadmin::Heimdal -- Wallet Kerberos administration API for Heimdal. # # Written by Jon Robertson -# Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2009, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm index c191bc9..b633e67 100644 --- a/perl/Wallet/Kadmin/MIT.pm +++ b/perl/Wallet/Kadmin/MIT.pm @@ -3,7 +3,7 @@ # Written by Russ Allbery # Pulled into a module by Jon Robertson # Copyright 2007, 2008, 2009, 2010 -# Board of Trustees, Leland Stanford Jr. University +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Object/File.pm b/perl/Wallet/Object/File.pm index 69468e1..49589f1 100644 --- a/perl/Wallet/Object/File.pm +++ b/perl/Wallet/Object/File.pm @@ -1,7 +1,8 @@ # Wallet::Object::File -- File object implementation for the wallet. # # Written by Russ Allbery -# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index 962c19b..e00747b 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -1,8 +1,8 @@ # Wallet::Object::Keytab -- Keytab object implementation for the wallet. # # Written by Russ Allbery -# Copyright 2007, 2008, 2009, 2010 -# Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2009, 2010, 2013 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/Wallet/Report.pm b/perl/Wallet/Report.pm index ff25b3a..b27a998 100644 --- a/perl/Wallet/Report.pm +++ b/perl/Wallet/Report.pm @@ -1,7 +1,8 @@ # Wallet::Report -- Wallet system reporting interface. # # Written by Russ Allbery -# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010, 2013 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/create-ddl b/perl/create-ddl index 62deb86..10f126a 100755 --- a/perl/create-ddl +++ b/perl/create-ddl @@ -3,7 +3,8 @@ # create-ddl - Create DDL files for Wallet # # Written by Jon Robertson -# Copyright 2012 Board of Trustees, Leland Stanford Jr. University +# Copyright 2012 +# The Board of Trustees of the Leland Stanford Junior University ############################################################################# # Modules and declarations diff --git a/perl/t/acl.t b/perl/t/acl.t index 62eb411..26b4903 100755 --- a/perl/t/acl.t +++ b/perl/t/acl.t @@ -3,7 +3,8 @@ # Tests for the wallet ACL API. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/config.t b/perl/t/config.t index 6b9f226..543e5d6 100755 --- a/perl/t/config.t +++ b/perl/t/config.t @@ -3,7 +3,8 @@ # Tests for the wallet server configuration. # # Written by Russ Allbery -# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/file.t b/perl/t/file.t index f902fba..5cb7c35 100755 --- a/perl/t/file.t +++ b/perl/t/file.t @@ -3,7 +3,8 @@ # Tests for the file object implementation. # # Written by Russ Allbery -# Copyright 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/init.t b/perl/t/init.t index aa028e3..142f54c 100755 --- a/perl/t/init.t +++ b/perl/t/init.t @@ -3,7 +3,8 @@ # Tests for database initialization. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/keytab.t b/perl/t/keytab.t index 561f130..3ced592 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -4,7 +4,7 @@ # # Written by Russ Allbery # Copyright 2007, 2008, 2009, 2010 -# Board of Trustees, Leland Stanford Jr. University +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/lib/Util.pm b/perl/t/lib/Util.pm index c15ccfe..3e606fe 100644 --- a/perl/t/lib/Util.pm +++ b/perl/t/lib/Util.pm @@ -1,7 +1,8 @@ # Utility class for wallet tests. # # Written by Russ Allbery -# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/pod.t b/perl/t/pod.t index c467b82..dc5f468 100755 --- a/perl/t/pod.t +++ b/perl/t/pod.t @@ -3,7 +3,8 @@ # Test POD formatting for the wallet Perl modules. # # Written by Russ Allbery -# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/report.t b/perl/t/report.t index 13ef7b6..a6b85df 100755 --- a/perl/t/report.t +++ b/perl/t/report.t @@ -3,7 +3,8 @@ # Tests for the wallet reporting interface. # # Written by Russ Allbery -# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/verifier-netdb.t b/perl/t/verifier-netdb.t index 6bd4e73..398cc6a 100755 --- a/perl/t/verifier-netdb.t +++ b/perl/t/verifier-netdb.t @@ -7,7 +7,8 @@ # environments. # # Written by Russ Allbery -# Copyright 2008 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/perl/t/verifier.t b/perl/t/verifier.t index f56f5fa..75f1afa 100755 --- a/perl/t/verifier.t +++ b/perl/t/verifier.t @@ -3,7 +3,8 @@ # Tests for the basic wallet ACL verifiers. # # Written by Russ Allbery -# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/server/keytab-backend b/server/keytab-backend index 7b6adb4..3ea3df0 100755 --- a/server/keytab-backend +++ b/server/keytab-backend @@ -18,7 +18,7 @@ # # Written by Russ Allbery # Copyright 2006, 2007, 2008, 2010 -# Board of Trustees, Leland Stanford Jr. University +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/server/wallet-report b/server/wallet-report index 992f5b8..0fd8aa9 100755 --- a/server/wallet-report +++ b/server/wallet-report @@ -3,7 +3,8 @@ # wallet-report -- Wallet server reporting interface. # # Written by Russ Allbery -# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/client/basic-t.in b/tests/client/basic-t.in index 11f0bce..836f394 100644 --- a/tests/client/basic-t.in +++ b/tests/client/basic-t.in @@ -4,7 +4,7 @@ # # Written by Russ Allbery # Copyright 2006, 2007, 2008, 2010 -# Board of Trustees, Leland Stanford Jr. University +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/client/full-t.in b/tests/client/full-t.in index 680e78f..ebdba03 100644 --- a/tests/client/full-t.in +++ b/tests/client/full-t.in @@ -3,7 +3,8 @@ # End-to-end tests for the wallet client. # # Written by Russ Allbery -# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/client/prompt-t.in b/tests/client/prompt-t.in index 682cd70..06991cc 100644 --- a/tests/client/prompt-t.in +++ b/tests/client/prompt-t.in @@ -3,7 +3,8 @@ # Password prompting tests for the wallet client. # # Written by Russ Allbery -# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/client/rekey-t.in b/tests/client/rekey-t.in index 390a362..0cfcb5d 100644 --- a/tests/client/rekey-t.in +++ b/tests/client/rekey-t.in @@ -4,7 +4,7 @@ # # Written by Russ Allbery # Copyright 2006, 2007, 2008, 2010 -# Board of Trustees, Leland Stanford Jr. University +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/data/cmd-fake b/tests/data/cmd-fake index add72fc..11791a6 100755 --- a/tests/data/cmd-fake +++ b/tests/data/cmd-fake @@ -4,7 +4,9 @@ # the client test suite. It doesn't test any of the wallet server code. # # Written by Russ Allbery -# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007, 2008, 2010 +# The Board of Trustees of the Leland Stanford Junior University +# # See LICENSE for licensing terms. command="$1" diff --git a/tests/data/fake-kadmin b/tests/data/fake-kadmin index 4c0ceac..c073ea5 100755 --- a/tests/data/fake-kadmin +++ b/tests/data/fake-kadmin @@ -3,7 +3,8 @@ # Fake kadmin.local used to test the keytab backend. # # Written by Russ Allbery -# Copyright 2007 Board of Trustees, Leland Stanford Jr. University +# Copyright 2007 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/server/keytab-t b/tests/server/keytab-t index 2a0ceed..a9f5450 100755 --- a/tests/server/keytab-t +++ b/tests/server/keytab-t @@ -3,7 +3,8 @@ # Tests for the keytab-backend dispatch code. # # Written by Russ Allbery -# Copyright 2006, 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2006, 2007, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. diff --git a/tests/server/report-t b/tests/server/report-t index 0771946..43ec9d1 100755 --- a/tests/server/report-t +++ b/tests/server/report-t @@ -3,7 +3,8 @@ # Tests for the wallet-report dispatch code. # # Written by Russ Allbery -# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University +# Copyright 2008, 2009, 2010 +# The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. -- cgit v1.2.3