summaryrefslogtreecommitdiff
path: root/rt/lib/RT/Scrips_Overlay.pm
diff options
context:
space:
mode:
Diffstat (limited to 'rt/lib/RT/Scrips_Overlay.pm')
-rw-r--r--rt/lib/RT/Scrips_Overlay.pm65
1 files changed, 62 insertions, 3 deletions
diff --git a/rt/lib/RT/Scrips_Overlay.pm b/rt/lib/RT/Scrips_Overlay.pm
index eecf29352..5dd83b72c 100644
--- a/rt/lib/RT/Scrips_Overlay.pm
+++ b/rt/lib/RT/Scrips_Overlay.pm
@@ -185,6 +185,15 @@ Commit all of this object's prepared scrips
sub Commit {
my $self = shift;
+ # RT::Scrips->_SetupSourceObjects will clobber
+ # the CurrentUser, but we need to keep this ticket
+ # so that the _TransactionBatch cache is maintained
+ # and doesn't run twice. sigh.
+ $self->_StashCurrentUser( TicketObj => $self->{TicketObj} ) if $self->{TicketObj};
+
+ #We're really going to need a non-acled ticket for the scrips to work
+ $self->_SetupSourceObjects( TicketObj => $self->{'TicketObj'},
+ TransactionObj => $self->{'TransactionObj'} );
foreach my $scrip (@{$self->Prepared}) {
$RT::Logger->debug(
@@ -196,6 +205,9 @@ sub Commit {
$scrip->Commit( TicketObj => $self->{'TicketObj'},
TransactionObj => $self->{'TransactionObj'} );
}
+
+ # Apply the bandaid.
+ $self->_RestoreCurrentUser( TicketObj => $self->{TicketObj} ) if $self->{TicketObj};
}
@@ -216,6 +228,12 @@ sub Prepare {
Type => undef,
@_ );
+ # RT::Scrips->_SetupSourceObjects will clobber
+ # the CurrentUser, but we need to keep this ticket
+ # so that the _TransactionBatch cache is maintained
+ # and doesn't run twice. sigh.
+ $self->_StashCurrentUser( TicketObj => $args{TicketObj} ) if $args{TicketObj};
+
#We're really going to need a non-acled ticket for the scrips to work
$self->_SetupSourceObjects( TicketObj => $args{'TicketObj'},
Ticket => $args{'Ticket'},
@@ -248,6 +266,10 @@ sub Prepare {
}
+ # Apply the bandaid.
+ $self->_RestoreCurrentUser( TicketObj => $args{TicketObj} ) if $args{TicketObj};
+
+
return (@{$self->Prepared});
};
@@ -264,6 +286,39 @@ sub Prepared {
return ($self->{'prepared_scrips'} || []);
}
+=head2 _StashCurrentUser TicketObj => RT::Ticket
+
+Saves aside the current user of the original ticket that was passed to these scrips.
+This is used to make sure that we don't accidentally leak the RT_System current user
+back to the calling code.
+
+=cut
+
+sub _StashCurrentUser {
+ my $self = shift;
+ my %args = @_;
+
+ $self->{_TicketCurrentUser} = $args{TicketObj}->CurrentUser;
+}
+
+=head2 _RestoreCurrentUser TicketObj => RT::Ticket
+
+Uses the current user saved by _StashCurrentUser to reset a Ticket object
+back to the caller's current user and avoid leaking an RT_System ticket to
+calling code.
+
+=cut
+
+sub _RestoreCurrentUser {
+ my $self = shift;
+ my %args = @_;
+ unless ( $self->{_TicketCurrentUser} ) {
+ RT->Logger->debug("Called _RestoreCurrentUser without a stashed current user object");
+ return;
+ }
+ $args{TicketObj}->CurrentUser($self->{_TicketCurrentUser});
+
+}
# {{{ sup _SetupSourceObjects
@@ -288,9 +343,13 @@ sub _SetupSourceObjects {
@_ );
- if ( $args{'TicketObj'} ) {
- # clone the ticket here as we need to change CurrentUser
- $self->{'TicketObj'} = bless { %{$args{'TicketObj'} } }, 'RT::Ticket';
+ if ( $self->{'TicketObj'} = $args{'TicketObj'} ) {
+ # This clobbers the passed in TicketObj by turning it into one
+ # whose current user is RT_System. Anywhere in the Web UI
+ # currently calling into this is thus susceptable to a privilege
+ # leak; the only current call site is ->Apply, which bandaids
+ # over the top of this by re-asserting the CurrentUser
+ # afterwards.
$self->{'TicketObj'}->CurrentUser( $self->CurrentUser );
}
else {