diff options
| -rw-r--r-- | perl/Wallet/Object/Base.pm | 16 | ||||
| -rw-r--r-- | perl/Wallet/Object/Keytab.pm | 10 | ||||
| -rwxr-xr-x | perl/t/keytab.t | 14 | ||||
| -rwxr-xr-x | perl/t/object.t | 52 | ||||
| -rwxr-xr-x | perl/t/server.t | 33 | 
5 files changed, 116 insertions, 9 deletions
| diff --git a/perl/Wallet/Object/Base.pm b/perl/Wallet/Object/Base.pm index 8d01ae8..10864b7 100644 --- a/perl/Wallet/Object/Base.pm +++ b/perl/Wallet/Object/Base.pm @@ -198,6 +198,10 @@ sub _set_internal {      $time ||= time;      my $name = $self->{name};      my $type = $self->{type}; +    if ($self->flag_check ('locked')) { +        $self->error ("cannot modify ${type}:${name}: object is locked"); +        return; +    }      eval {          my $sql = "select ob_$attr from objects where ob_type = ? and              ob_name = ?"; @@ -425,6 +429,10 @@ sub get { die "Do not instantiate Wallet::Object::Base directly\n"; }  sub store {      my ($self, $data, $user, $host, $time) = @_;      my $id = $self->{type} . ':' . $self->{name}; +    if ($self->flag_check ('locked')) { +        $self->error ("cannot store $id: object is locked"); +        return; +    }      $self->error ("cannot store $id: object type is immutable");      return;  } @@ -508,6 +516,10 @@ sub destroy {      $time ||= time;      my $name = $self->{name};      my $type = $self->{type}; +    if ($self->flag_check ('locked')) { +        $self->error ("cannot destroy ${type}:${name}: object is locked"); +        return; +    }      eval {          my $sql = 'delete from flags where fl_type = ? and fl_name = ?';          $self->{dbh}->do ($sql, undef, $type, $name); @@ -596,6 +608,10 @@ 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(). +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]]) diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index 38e0938..e4a41cd 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -187,6 +187,11 @@ sub create {  # Override destroy to delete the principal out of Kerberos as well.  sub destroy {      my ($self, $user, $host, $time) = @_; +    my $id = $self->{type} . ':' . $self->{name}; +    if ($self->flag_check ('locked')) { +        $self->error ("cannot destroy $id: object is locked"); +        return; +    }      return undef if not $self->_kadmin_delprinc ($self->{name});      return $self->SUPER::destroy ($user, $host, $time);  } @@ -196,6 +201,11 @@ sub destroy {  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; +    }      unless (defined ($Wallet::Config::KEYTAB_TMP)) {          $self->error ('KEYTAB_TMP configuration variable not set');          return undef; diff --git a/perl/t/keytab.t b/perl/t/keytab.t index 360065d..9337c80 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -3,7 +3,7 @@  #  # t/keytab.t -- Tests for the keytab object implementation. -use Test::More tests => 38; +use Test::More tests => 46;  use Wallet::Config;  use Wallet::Object::Keytab; @@ -162,6 +162,12 @@ SKIP: {      $object = Wallet::Object::Keytab->new ('keytab', 'wallet/one', $dbh);      ok (defined ($object), 'Retrieving the object works');      ok ($object->isa ('Wallet::Object::Keytab'), ' and is the right type'); +    is ($object->flag_set ('locked', @trace), 1, ' and setting locked works'); +    is ($object->get (@trace), undef, ' and get fails'); +    is ($object->error, "cannot get keytab:wallet/one: object is locked", +        ' because it is locked'); +    is ($object->flag_clear ('locked', @trace), 1, +        ' and clearing locked works');      my $data = $object->get (@trace);      if (defined ($data)) {          ok (defined ($data), ' and getting the keytab works'); @@ -220,6 +226,12 @@ EOO      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", +        ' because it is locked'); +    is ($object->flag_clear ('locked', @trace), 1, +        ' and clearing locked works');      is ($object->destroy (@trace), 1, ' and destroying it succeeds');      ok (! created ('wallet/one'), ' and now it does not exist'); diff --git a/perl/t/object.t b/perl/t/object.t index db7cb98..0349f28 100755 --- a/perl/t/object.t +++ b/perl/t/object.t @@ -3,7 +3,7 @@  #  # t/object.t -- Tests for the basic object implementation. -use Test::More tests => 93; +use Test::More tests => 118;  use Wallet::ACL;  use Wallet::Config; @@ -150,8 +150,27 @@ if ($object->flag_set ('locked', @trace)) {      is ($object->error, '', ' and setting it again works');  } -# Test stub methods. -eval { $object->get }; +# Test stub methods and locked status. +is ($object->store ("Some data", @trace), undef, 'Store fails'); +is ($object->error, "cannot store keytab:${princ}: object is locked", +    ' because the object is locked'); +is ($object->owner ('', @trace), undef, ' and owner fails'); +is ($object->error, "cannot modify keytab:${princ}: object is locked", +    ' for the same reason'); +is ($object->expires ('', @trace), undef, ' and expires fails'); +is ($object->error, "cannot modify keytab:${princ}: object is locked", +    ' for the same reason'); +for my $acl (qw/get store show destroy flags/) { +    is ($object->acl ($acl, '', @trace), undef, " and setting $acl ACL fails"); +    is ($object->error, "cannot modify keytab:${princ}: object is locked", +        ' for the same reason'); +} +is ($object->flag_check ('locked'), 1, ' and checking flags works'); +@flags = $object->flag_list; +is (scalar (@flags), 2, ' and listing flags works'); +is ("@flags", 'locked unchanging', ' and returns the right data'); +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->store ("Some data", @trace), 'Store fails'); @@ -169,7 +188,7 @@ my $output = <<"EOO";      Destroy ACL: ADMIN        Flags ACL: ADMIN          Expires: $now -          Flags: locked unchanging +          Flags: unchanging       Created by: $user     Created from: $host       Created on: $created @@ -178,8 +197,33 @@ Members of ACL ADMIN (id: 1) are:    krb5 $user  EOO  is ($object->show, $output, 'Show output is correct'); +is ($object->flag_set ('locked', @trace), 1, ' and setting locked works'); +$output = <<"EOO"; +           Type: keytab +           Name: $princ +          Owner: ADMIN +        Get ACL: ADMIN +      Store ACL: ADMIN +       Show ACL: ADMIN +    Destroy ACL: ADMIN +      Flags ACL: ADMIN +        Expires: $now +          Flags: locked unchanging +     Created by: $user +   Created from: $host +     Created on: $created + +Members of ACL ADMIN (id: 1) are: +  krb5 $user +EOO +is ($object->show, $output, ' and show still works and is correct');  # Test destroy. +is ($object->destroy (@trace), undef, 'Destroy fails'); +is ($object->error, "cannot destroy keytab:${princ}: object is locked", +    ' because of the locked status'); +is ($object->flag_clear ('locked', @trace), 1, +    ' and clearing locked status works');  if ($object->destroy (@trace)) {      ok (1, 'Destroy is successful');  } else { diff --git a/perl/t/server.t b/perl/t/server.t index 8dc2b89..e061f1a 100755 --- a/perl/t/server.t +++ b/perl/t/server.t @@ -3,7 +3,7 @@  #  # t/server.t -- Tests for the wallet server API. -use Test::More tests => 241; +use Test::More tests => 261;  use Wallet::Config;  use Wallet::Server; @@ -300,6 +300,8 @@ is ($server->store ('base', 'service/admin', 'stuff'), undef,      ' and now store fails');  is ($server->error, "$admin not authorized to store base:service/admin",      ' due to permissions again'); +is ($server->owner ('base', 'service/admin', 'ADMIN'), 1, +    ' and setting the owner again works');  # Test manipulating flags.  is ($server->flag_clear ('base', 'service/admin', 'locked'), undef, @@ -312,8 +314,27 @@ if ($server->flag_set ('base', 'service/admin', 'locked')) {  } else {      is ($server->error, '', ' but setting it works');  } +is ($server->store ('base', 'service/admin', 'stuff'), undef, +    ' now store fails'); +is ($server->error, 'cannot store base:service/admin: object is locked', +    ' because the object is locked'); +is ($server->expires ('base', 'service/admin', ''), undef, +    ' and expires fails'); +is ($server->error, 'cannot modify base:service/admin: object is locked', +    ' because the object is locked'); +is ($server->owner ('base', 'service/admin', ''), undef, ' and owner fails'); +is ($server->error, 'cannot modify base:service/admin: object is locked', +    ' because the object is locked'); +for my $acl (qw/get store show destroy flags/) { +    is ($server->acl ('base', 'service/admin', $acl, ''), undef, +        " and setting $acl ACL fails"); +    is ($server->error, 'cannot modify base:service/admin: object is locked', +        ' for the same reason'); +}  is ($server->flag_clear ('base', 'service/admin', 'locked'), 1,      ' and then clearing it works'); +is ($server->owner ('base', 'service/admin', ''), 1, +    ' and then clearing owner works');  is ($server->flag_set ('base', 'service/admin', 'unchanging'), 1,      ' and setting unchanging works');  is ($server->flag_clear ('base', 'service/admin', 'locked'), undef, @@ -438,8 +459,6 @@ is ($server->error,  is ($server->flag_set ('base', 'service/both', 'unchanging'), 1,      ' and set flags on an object we have an ACL');  is ($server->flag_set ('base', 'service/both', 'locked'), 1, ' both flags'); -is ($server->flag_clear ('base', 'service/both', 'locked'), 1, -    ' and clear flags');  $show = $server->show ('base', 'service/both');  $show =~ s/(Created on:) \d+$/$1 0/m;  $expected = <<"EOO"; @@ -449,7 +468,7 @@ $expected = <<"EOO";         Show ACL: user1      Destroy ACL: user2        Flags ACL: user1 -          Flags: unchanging +          Flags: locked unchanging       Created by: $admin     Created from: $host       Created on: 0 @@ -465,6 +484,12 @@ Members of ACL user2 (id: 3) are:    krb5 $user2  EOO  is ($show, $expected, ' and show an object we jointly own'); +is ($server->store ('base', 'service/both', 'stuff'), undef, +    ' but not store data'); +is ($server->error, 'cannot store base:service/both: object is locked', +    ' when the object is locked'); +is ($server->flag_clear ('base', 'service/both', 'locked'), 1, +    ' and clear flags');  is ($server->destroy ('base', 'service/both'), undef,      ' but not destroy it');  is ($server->error, "$user1 not authorized to destroy base:service/both", | 
