summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--perl/Wallet/Object/Base.pm16
-rw-r--r--perl/Wallet/Object/Keytab.pm10
-rwxr-xr-xperl/t/keytab.t14
-rwxr-xr-xperl/t/object.t52
-rwxr-xr-xperl/t/server.t33
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",