From 0e16def8a9e12f9b2232b29da79cdacb6710b086 Mon Sep 17 00:00:00 2001 From: Jon Robertson Date: Fri, 6 Feb 2015 23:43:50 -0800 Subject: Added acl replace command to wallet backend New command for replacing the ownership of anything owned by a specific ACL with another ACL. This differs from acl rename in that it's to be used when the destination ACL already exists and potentially already owns some objects. Change-Id: I765bebf499fe0f861abc2ffe1873990590beed36 --- server/wallet-backend | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'server/wallet-backend') diff --git a/server/wallet-backend b/server/wallet-backend index 8dfc952..dcf2300 100755 --- a/server/wallet-backend +++ b/server/wallet-backend @@ -173,6 +173,9 @@ sub command { } elsif ($action eq 'rename') { check_args (2, 2, [], @args); $server->acl_rename (@args) or failure ($server->error, @_); + } elsif ($action eq 'replace') { + check_args (2, 2, [], @args); + $server->acl_replace (@args) or failure ($server->error, @_); } elsif ($action eq 'show') { check_args (1, 1, [], @args); my $output = $server->acl_show (@args); @@ -449,6 +452,25 @@ accidental lockout, but administrators can remove themselves from the C ACL and can leave only a non-functioning entry on the ACL. Use caution when removing entries from the C ACL. +=item acl rename + +Renames the ACL identified by to . This changes the +human-readable name, not the underlying numeric ID, so the ACL's +associations with objects will be unchanged. The C ACL may not be +renamed. may be either the current name or the numeric ID. +must not be all-numeric. To rename an ACL, the current user must be +authorized by the C ACL. + +=item acl replace + +Find any objects owned by , and then change their ownership to + instead. should already exist, and may already have +some objects owned by it. is not deleted afterwards, though in +most cases that is probably your next step. The C ACL may not be +replaced from. and may be either the current name or the +numeric ID. To replace an ACL, the current user must be authorized by +the C ACL. + =item acl show Display the name, numeric ID, and entries of the ACL . -- cgit v1.2.3 From 000b338694fae87996220336678fe990a1c3e3e1 Mon Sep 17 00:00:00 2001 From: Jon Robertson Date: Wed, 18 Feb 2015 15:17:51 -0800 Subject: Added new method for wallet-backend, update update will work generally like get, but only for objects that have a concept of updating content automatically, like keytabs and passwords. For these, the content will be updated before sending to the client. In a later release get for keytabs will be modified to never update the kvno before sending to the user, and so the unchanging flag will be phased out in lieu of explicitly using the method that does what you want. Change-Id: I96a84416c5e50278eb29fe07052dde6e063bc071 --- NEWS | 9 ++++++ client/wallet.pod | 13 +++++++++ perl/lib/Wallet/Object/Base.pm | 9 ++++++ perl/lib/Wallet/Object/Keytab.pm | 59 ++++++++++++++++++++++++++------------ perl/lib/Wallet/Object/Password.pm | 32 ++++++++++++++++----- perl/lib/Wallet/Server.pm | 15 ++++++++++ perl/t/object/base.t | 5 +++- perl/t/object/password.t | 8 +++++- server/wallet-backend | 16 +++++++++++ 9 files changed, 138 insertions(+), 28 deletions(-) (limited to 'server/wallet-backend') diff --git a/NEWS b/NEWS index 64c0fbc..664da05 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,15 @@ wallet 1.3 (xxxx-xx-xx) generate content for the object if you do a get before storing any content inside it. + Added a new command to wallet-backend, update. This will update the + contents of an object before running a get on it, and is only valid + for objects that can automatically get new content, such as keytab + and password objects. A keytab will get a new kvno regardless of + the unchanging flag if called with update. In a future release get + will be changed to never update a keytab, and the unchanging flag + will be ignored. Please start moving to use get or update as the + situation warrants. + Added an acl replace command, to change all objects owned by one ACL to be owned by another. diff --git a/client/wallet.pod b/client/wallet.pod index 20d1874..672f0e4 100644 --- a/client/wallet.pod +++ b/client/wallet.pod @@ -385,6 +385,19 @@ If an object with type and name does not already exist when this command is issued (as checked with the check interface), B will attempt to automatically create it (using autocreate). +=item update + +Prints to standard output the data associated with the object identified +by and , or stores it in a file if the B<-f> option was +given. This will generate new data in the object, and only works for +objects that support generating new data automatically, such as keytabs or +passwords. Types that do not support generating new data will fail and +direct you to use get instead. + +If an object with type and name does not already exist when +this command is issued (as checked with the check interface), B +will attempt to automatically create it (using autocreate). + =back =head1 ATTRIBUTES diff --git a/perl/lib/Wallet/Object/Base.pm b/perl/lib/Wallet/Object/Base.pm index bdd61fb..97e6127 100644 --- a/perl/lib/Wallet/Object/Base.pm +++ b/perl/lib/Wallet/Object/Base.pm @@ -609,6 +609,15 @@ sub history { # The get methods must always be overridden by the subclass. sub get { die "Do not instantiate Wallet::Object::Base directly\n"; } +# The update method should only work if a subclass supports it as something +# different from get. That makes it explicit about whether the subclass has +# a meaningful update. +sub update { + my ($self) = @_; + $self->error ("update is not supported for this type, use get instead"); + return; +} + # Provide a default store implementation that returns an immutable object # error so that auto-generated types don't have to provide their own. sub store { diff --git a/perl/lib/Wallet/Object/Keytab.pm b/perl/lib/Wallet/Object/Keytab.pm index 975179b..c625766 100644 --- a/perl/lib/Wallet/Object/Keytab.pm +++ b/perl/lib/Wallet/Object/Keytab.pm @@ -28,6 +28,37 @@ use Wallet::Kadmin; # that it will sort properly. $VERSION = '0.09'; +############################################################################## +# Shared methods +############################################################################## + +# Generate a keytab into a temporary file and then return that as the return +# value. Used by both get and update, as the only difference is how we +# handle the unchanging flag. +sub retrieve { + my ($self, $operation, $user, $host, $time) = @_; + $time ||= time; + my $id = $self->{type} . ':' . $self->{name}; + if ($self->flag_check ('locked')) { + $self->error ("cannot get $id: object is locked"); + return; + } + my $kadmin = $self->{kadmin}; + my $result; + if ($operation eq 'get' && $self->flag_check ('unchanging')) { + $result = $kadmin->keytab ($self->{name}); + } else { + my @enctypes = $self->attr ('enctypes'); + $result = $kadmin->keytab_rekey ($self->{name}, @enctypes); + } + if (defined $result) { + $self->log_action ($operation, $user, $host, $time); + } else { + $self->error ($kadmin->error); + } + return $result; +} + ############################################################################## # Enctype restriction ############################################################################## @@ -314,25 +345,15 @@ sub destroy { # return that as the return value. sub get { my ($self, $user, $host, $time) = @_; - $time ||= time; - my $id = $self->{type} . ':' . $self->{name}; - if ($self->flag_check ('locked')) { - $self->error ("cannot get $id: object is locked"); - return; - } - my $kadmin = $self->{kadmin}; - my $result; - if ($self->flag_check ('unchanging')) { - $result = $kadmin->keytab ($self->{name}); - } else { - my @enctypes = $self->attr ('enctypes'); - $result = $kadmin->keytab_rekey ($self->{name}, @enctypes); - } - if (defined $result) { - $self->log_action ('get', $user, $host, $time); - } else { - $self->error ($kadmin->error); - } + my $result = $self->retrieve ('get', $user, $host, $time); + return $result; +} + +# Our update implementation. Generate a new keytab regardless of the +# unchanging flag. +sub update { + my ($self, $user, $host, $time) = @_; + my $result = $self->retrieve ('update', $user, $host, $time); return $result; } diff --git a/perl/lib/Wallet/Object/Password.pm b/perl/lib/Wallet/Object/Password.pm index d06c8a6..3fd6ec8 100644 --- a/perl/lib/Wallet/Object/Password.pm +++ b/perl/lib/Wallet/Object/Password.pm @@ -57,12 +57,12 @@ sub file_path { } ############################################################################## -# Core methods +# Shared methods ############################################################################## # Return the contents of the file. -sub get { - my ($self, $user, $host, $time) = @_; +sub retrieve { + my ($self, $operation, $user, $host, $time) = @_; $time ||= time; my $id = $self->{type} . ':' . $self->{name}; if ($self->flag_check ('locked')) { @@ -72,13 +72,13 @@ sub get { my $path = $self->file_path; return unless $path; - # If nothing is yet stored, generate a random password and save it to - # the file. + # If nothing is yet stored, or we have requested an update, generate a + # random password and save it to the file. my $schema = $self->{schema}; my %search = (ob_type => $self->{type}, ob_name => $self->{name}); my $object = $schema->resultset('Object')->find (\%search); - unless ($object->ob_stored_on) { + if (!$object->ob_stored_on || $operation eq 'update') { unless (open (FILE, '>', $path)) { $self->error ("cannot store initial settings for $id: $!\n"); return; @@ -103,10 +103,28 @@ sub get { $self->error ("cannot get $id: $!"); return; } - $self->log_action ('get', $user, $host, $time); + $self->log_action ($operation, $user, $host, $time); return $data; } +############################################################################## +# Core methods +############################################################################## + +# Return the contents of the file. +sub get { + my ($self, $user, $host, $time) = @_; + my $result = $self->retrieve ('get', $user, $host, $time); + return $result; +} + +# Return the contents of the file after resetting them to a random string. +sub update { + my ($self, $user, $host, $time) = @_; + my $result = $self->retrieve ('update', $user, $host, $time); + return $result; +} + 1; __END__ diff --git a/perl/lib/Wallet/Server.pm b/perl/lib/Wallet/Server.pm index 6af0570..3ef5954 100644 --- a/perl/lib/Wallet/Server.pm +++ b/perl/lib/Wallet/Server.pm @@ -516,6 +516,21 @@ sub get { return $result; } +# Retrieve the information associated with an object, updating the current +# information if we are of a type that allows autogenerated information. +# Returns undef and sets the internal error if the retrieval fails or if the +# user isn't authorized. If the object doesn't exist, attempts dynamic +# creation of the object using the default ACL mappings (if any). +sub update { + my ($self, $type, $name) = @_; + my $object = $self->retrieve ($type, $name); + return unless defined $object; + return unless $self->acl_verify ($object, 'get'); + my $result = $object->update ($self->{user}, $self->{host}); + $self->error ($object->error) unless defined $result; + return $result; +} + # Store new data in an object, or returns undef and sets the internal error if # the object can't be found or if the user isn't authorized. Also don't # permit storing undef, although storing the empty string is fine. If the diff --git a/perl/t/object/base.t b/perl/t/object/base.t index ee9ff4b..8fedd64 100755 --- a/perl/t/object/base.t +++ b/perl/t/object/base.t @@ -12,7 +12,7 @@ use strict; use warnings; use POSIX qw(strftime); -use Test::More tests => 137; +use Test::More tests => 139; use Wallet::ACL; use Wallet::Admin; @@ -208,6 +208,9 @@ is ($object->flag_clear ('locked', @trace), 1, 'Clearing locked succeeds'); eval { $object->get (@trace) }; is ($@, "Do not instantiate Wallet::Object::Base directly\n", 'Get fails with the right error'); +ok (!$object->update (@trace), 'Update fails'); +is ($object->error, 'update is not supported for this type, use get instead', + ' with the right error'); ok (! $object->store ("Some data", @trace), 'Store fails'); is ($object->error, "cannot store keytab:$princ: object type is immutable", ' with the right error'); diff --git a/perl/t/object/password.t b/perl/t/object/password.t index c0f2fbc..4fe6b50 100644 --- a/perl/t/object/password.t +++ b/perl/t/object/password.t @@ -13,7 +13,7 @@ use strict; use warnings; use POSIX qw(strftime); -use Test::More tests => 31; +use Test::More tests => 33; use Wallet::Admin; use Wallet::Config; @@ -111,6 +111,12 @@ ok (-f 'test-files/09/test', ' and the file exists'); is (contents ('test-files/09/test'), 'bar', ' with the right contents'); is ($object->get (@trace), "bar\n\0baz\n", ' and get returns correctly'); +# And check to make sure update changes the contents. +$pwd = $object->update (@trace); +isnt ($pwd, "bar\n\0baz\n", 'Update changes the contents'); +like ($pwd, qr{^.{$Wallet::Config::PWD_LENGTH_MIN}$}, + ' to a random password string of the right length'); + # Clean up. $admin->destroy; END { diff --git a/server/wallet-backend b/server/wallet-backend index dcf2300..ea3e21e 100755 --- a/server/wallet-backend +++ b/server/wallet-backend @@ -315,6 +315,14 @@ sub command { } splice (@_, 3); $server->store (@args) or failure ($server->error, @_); + } elsif ($command eq 'update') { + check_args (2, 2, [], @args); + my $output = $server->update (@args); + if (defined $output) { + print $output; + } else { + failure ($server->error, @_); + } } else { error "unknown command $command"; } @@ -611,6 +619,14 @@ Stores for the object identified by and for later retrieval with C. Not all object types support this. If is not given as an argument, it will be read from standard input. +=item update + +Prints to standard output the data associated with the object identified +by and . If the object is one that can have changing +information, such as a keytab or password, then we generate new data for +that object regardless of whether there is current data or the unchanging +flag is set. + =back =head1 ATTRIBUTES -- cgit v1.2.3 From 884297fc439a4c3eba2365cdb810214dfc4f5799 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Sun, 17 Jan 2016 12:39:57 -0800 Subject: Update Perl version declaration and warnings for server scripts Add use 5.008 and use warnings uniformly to all of the server backend scripts. --- server/keytab-backend | 5 +---- server/wallet-admin | 9 ++++----- server/wallet-backend | 5 +---- server/wallet-report | 9 ++++----- 4 files changed, 10 insertions(+), 18 deletions(-) (limited to 'server/wallet-backend') diff --git a/server/keytab-backend b/server/keytab-backend index bd5a3f9..6e47331 100755 --- a/server/keytab-backend +++ b/server/keytab-backend @@ -16,10 +16,7 @@ # # The keytab for the extracted principal will be printed to standard output. -############################################################################## -# Declarations and site configuration -############################################################################## - +use 5.008; use strict; use warnings; diff --git a/server/wallet-admin b/server/wallet-admin index 7ba1021..e74b2f1 100755 --- a/server/wallet-admin +++ b/server/wallet-admin @@ -1,12 +1,11 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # # Wallet server administrative commands. -############################################################################## -# Declarations and site configuration -############################################################################## - +use 5.008; use strict; +use warnings; + use Wallet::Admin; ############################################################################## diff --git a/server/wallet-backend b/server/wallet-backend index ea3e21e..aa83a96 100755 --- a/server/wallet-backend +++ b/server/wallet-backend @@ -2,10 +2,7 @@ # # Wallet server for storing and retrieving secure data. -############################################################################## -# Declarations and site configuration -############################################################################## - +use 5.008; use strict; use warnings; diff --git a/server/wallet-report b/server/wallet-report index 22637ca..6508227 100755 --- a/server/wallet-report +++ b/server/wallet-report @@ -1,12 +1,11 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # # Wallet server reporting interface. -############################################################################## -# Declarations and globals -############################################################################## - +use 5.008; use strict; +use warnings; + use Wallet::Report; # The help output, sent in reply to the help command. Lists each supported -- cgit v1.2.3