Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Please unblock package request-tracker4 This contains fixes for important bugs only. debdiff against 4.0.7-2 (the version currently in testing) attached. unblock request-tracker4/4.0.7-4 -- System Information: Debian Release: wheezy/sid APT prefers testing APT policy: (500, 'testing') Architecture: i386 (i686) Kernel: Linux 3.2.0-4-686-pae (SMP w/2 CPU cores) Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash
diff -Nru request-tracker4-4.0.7/debian/changelog request-tracker4-4.0.7/debian/changelog --- request-tracker4-4.0.7/debian/changelog 2012-10-23 10:59:00.000000000 +0100 +++ request-tracker4-4.0.7/debian/changelog 2012-12-16 14:08:32.000000000 +0000 @@ -1,3 +1,18 @@ +request-tracker4 (4.0.7-4) unstable; urgency=low + + * Add extra robustness to hostname handling (Closes: 685502) + + -- Dominic Hargreaves <d...@earth.li> Sun, 16 Dec 2012 14:08:31 +0000 + +request-tracker4 (4.0.7-3) unstable; urgency=low + + * Cherry-pick fix from 4.0.8 fixing duplicate transaction creation + bug (Closes: #691701) + * Remove unused code which uses Digest::SHA1 which in turn has been + removed from Debian (Closes: #694484) + + -- Dominic Hargreaves <d...@earth.li> Mon, 10 Dec 2012 14:13:24 +0000 + request-tracker4 (4.0.7-2) unstable; urgency=high * Multiple security fixes for: diff -Nru request-tracker4-4.0.7/debian/config request-tracker4-4.0.7/debian/config --- request-tracker4-4.0.7/debian/config 2012-10-15 17:50:27.000000000 +0100 +++ request-tracker4-4.0.7/debian/config 2012-12-16 14:01:42.000000000 +0000 @@ -112,7 +112,7 @@ db_version 2.0 db_capb backup -hostname="$(hostname -f)" +hostname="$(hostname -f || true)" hostname="${hostname:-$(hostname)}" # sane startup defaults diff -Nru request-tracker4-4.0.7/debian/patches/68_lock_transaction_updates request-tracker4-4.0.7/debian/patches/68_lock_transaction_updates --- request-tracker4-4.0.7/debian/patches/68_lock_transaction_updates 1970-01-01 01:00:00.000000000 +0100 +++ request-tracker4-4.0.7/debian/patches/68_lock_transaction_updates 2012-11-20 18:01:28.000000000 +0000 @@ -0,0 +1,185 @@ +From b99af56fa6fed07f2ea055e0abed393ce3c6fb4a Mon Sep 17 00:00:00 2001 +From: Alex Vandiver <ale...@bestpractical.com> +Date: Fri, 16 Mar 2012 16:57:07 -0400 +Subject: [PATCH] Lock transaction updates so scrips get a consistent snapshot + +Previously, nothing prevented multiple transactions from being run on +the system concurrently, and making identical changes. This could lead +to multiple Corrrespondences, followed by multiple "Status changed from +new to open" transactions. Prevent this by always running +->_NewTransaction in a database transaction, and ensuring that it takes +a write lock on the row before running scrips and purges the cache. +This ensures a coherent and serial execution of scrips. +--- + lib/RT/Record.pm | 35 +++++++++++++++++++++++++++++++++++ + lib/RT/Ticket.pm | 10 +++++++--- + t/ticket/race.t | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 93 insertions(+), 3 deletions(-) + create mode 100644 t/ticket/race.t + +diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm +index 29cff47..c116ee8 100644 +--- a/lib/RT/Record.pm ++++ b/lib/RT/Record.pm +@@ -1413,8 +1413,35 @@ sub _DeleteLink { + } + + ++=head1 LockForUpdate + ++In a database transaction, gains an exclusive lock on the row, to ++prevent race conditions. On SQLite, this is a "RESERVED" lock on the ++entire database. + ++=cut ++ ++sub LockForUpdate { ++ my $self = shift; ++ ++ my $pk = $self->_PrimaryKey; ++ my $id = @_ ? $_[0] : $self->$pk; ++ $self->_expire if $self->isa("DBIx::SearchBuilder::Record::Cachable"); ++ if (RT->Config->Get('DatabaseType') eq "SQLite") { ++ # SQLite does DB-level locking, upgrading the transaction to ++ # "RESERVED" on the first UPDATE/INSERT/DELETE. Do a no-op ++ # UPDATE to force the upgade. ++ return RT->DatabaseHandle->dbh->do( ++ "UPDATE " .$self->Table. ++ " SET $pk = $pk WHERE 1 = 0"); ++ } else { ++ return $self->_LoadFromSQL( ++ "SELECT * FROM ".$self->Table ++ ." WHERE $pk = ? FOR UPDATE", ++ $id, ++ ); ++ } ++} + + =head2 _NewTransaction PARAMHASH + +@@ -1441,6 +1468,11 @@ sub _NewTransaction { + @_ + ); + ++ my $in_txn = RT->DatabaseHandle->TransactionDepth; ++ RT->DatabaseHandle->BeginTransaction unless $in_txn; ++ ++ $self->LockForUpdate; ++ + my $old_ref = $args{'OldReference'}; + my $new_ref = $args{'NewReference'}; + my $ref_type = $args{'ReferenceType'}; +@@ -1487,6 +1519,9 @@ sub _NewTransaction { + if ( RT->Config->Get('UseTransactionBatch') and $transaction ) { + push @{$self->{_TransactionBatch}}, $trans if $args{'CommitScrips'}; + } ++ ++ RT->DatabaseHandle->Commit unless $in_txn; ++ + return ( $transaction, $msg, $trans ); + } + +diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm +index 3f2e94c..79fa036 100644 +--- a/lib/RT/Ticket.pm ++++ b/lib/RT/Ticket.pm +@@ -2095,14 +2095,16 @@ sub Comment { + } + $args{'NoteType'} = 'Comment'; + ++ $RT::Handle->BeginTransaction(); + if ($args{'DryRun'}) { +- $RT::Handle->BeginTransaction(); + $args{'CommitScrips'} = 0; + } + + my @results = $self->_RecordNote(%args); + if ($args{'DryRun'}) { + $RT::Handle->Rollback(); ++ } else { ++ $RT::Handle->Commit(); + } + + return(@results); +@@ -2141,10 +2143,10 @@ sub Correspond { + or ( $self->CurrentUserHasRight('ModifyTicket') ) ) { + return ( 0, $self->loc("Permission Denied"), undef ); + } ++ $args{'NoteType'} = 'Correspond'; + +- $args{'NoteType'} = 'Correspond'; ++ $RT::Handle->BeginTransaction(); + if ($args{'DryRun'}) { +- $RT::Handle->BeginTransaction(); + $args{'CommitScrips'} = 0; + } + +@@ -2161,6 +2163,8 @@ sub Correspond { + + if ($args{'DryRun'}) { + $RT::Handle->Rollback(); ++ } else { ++ $RT::Handle->Commit(); + } + + return (@results); +diff --git a/t/ticket/race.t b/t/ticket/race.t +new file mode 100644 +index 0000000..aa1150e +--- /dev/null ++++ b/t/ticket/race.t +@@ -0,0 +1,51 @@ ++use strict; ++use warnings; ++ ++use RT::Test tests => 2; ++ ++use constant KIDS => 50; ++ ++my $id; ++ ++{ ++ my $t = RT::Ticket->new( RT->SystemUser ); ++ ($id) = $t->Create( ++ Queue => "General", ++ Subject => "Race $$", ++ ); ++} ++ ++diag "Created ticket $id"; ++RT->DatabaseHandle->Disconnect; ++ ++my @kids; ++for (1..KIDS) { ++ if (my $pid = fork()) { ++ push @kids, $pid; ++ next; ++ } ++ ++ # In the kid, load up the ticket and correspond ++ RT->ConnectToDatabase; ++ my $t = RT::Ticket->new( RT->SystemUser ); ++ $t->Load( $id ); ++ $t->Correspond( Content => "Correspondence from PID $$" ); ++ undef $t; ++ exit 0; ++} ++ ++ ++diag "Forked @kids"; ++waitpid $_, 0 for @kids; ++diag "All kids finished corresponding"; ++ ++RT->ConnectToDatabase; ++my $t = RT::Ticket->new( RT->SystemUser ); ++$t->Load($id); ++my $txns = $t->Transactions; ++$txns->Limit( FIELD => 'Type', VALUE => 'Status' ); ++is($txns->Count, 1, "Only one transaction change recorded" ); ++ ++$txns = $t->Transactions; ++$txns->Limit( FIELD => 'Type', VALUE => 'Correspond' ); ++is($txns->Count, KIDS, "But all correspondences were recorded" ); +-- +1.7.10.4 + diff -Nru request-tracker4-4.0.7/debian/patches/69_remove_unused_authenticate_method request-tracker4-4.0.7/debian/patches/69_remove_unused_authenticate_method --- request-tracker4-4.0.7/debian/patches/69_remove_unused_authenticate_method 1970-01-01 01:00:00.000000000 +0100 +++ request-tracker4-4.0.7/debian/patches/69_remove_unused_authenticate_method 2012-12-10 14:10:38.000000000 +0000 @@ -0,0 +1,66 @@ +From ddd207807fff9e373ea665636b7363b03903982c Mon Sep 17 00:00:00 2001 +From: Alex Vandiver <ale...@bestpractical.com> +Date: Mon, 20 Jun 2011 14:02:44 -0400 +Subject: [PATCH] Remove the unused Authenticate method + +This method was added as part of an Atom feature, the functionality of +which was removed from core in ec3af9f and made into RTx-Atom, which +rolls its own version of this method. +--- + lib/RT/CurrentUser.pm | 40 ---------------------------------------- + 1 file changed, 40 deletions(-) + +diff --git a/lib/RT/CurrentUser.pm b/lib/RT/CurrentUser.pm +index 57ee1eb..6b04e46 100644 +--- a/lib/RT/CurrentUser.pm ++++ b/lib/RT/CurrentUser.pm +@@ -268,46 +268,6 @@ sub CurrentUser { + return shift; + } + +-=head2 Authenticate +- +-Takes $password, $created and $nonce, and returns a boolean value +-representing whether the authentication succeeded. +- +-If both $nonce and $created are specified, validate $password against: +- +- encode_base64(sha1( +- $nonce . +- $created . +- sha1_hex( "$username:$realm:$server_pass" ) +- )) +- +-where $server_pass is the md5_hex(password) digest stored in the +-database, $created is in ISO time format, and $nonce is a random +-string no longer than 32 bytes. +- +-=cut +- +-sub Authenticate { +- my ($self, $password, $created, $nonce, $realm) = @_; +- +- require Digest::MD5; +- require Digest::SHA1; +- require MIME::Base64; +- +- my $username = $self->UserObj->Name or return; +- my $server_pass = $self->UserObj->__Value('Password') or return; +- my $auth_digest = MIME::Base64::encode_base64(Digest::SHA1::sha1( +- $nonce . +- $created . +- Digest::MD5::md5_hex("$username:$realm:$server_pass") +- )); +- +- chomp($password); +- chomp($auth_digest); +- +- return ($password eq $auth_digest); +-} +- + RT::Base->_ImportOverlays(); + + 1; +-- +1.7.10.4 + diff -Nru request-tracker4-4.0.7/debian/patches/series request-tracker4-4.0.7/debian/patches/series --- request-tracker4-4.0.7/debian/patches/series 2012-10-23 10:50:16.000000000 +0100 +++ request-tracker4-4.0.7/debian/patches/series 2012-12-10 14:11:33.000000000 +0000 @@ -8,3 +8,5 @@ 65_rt_setup_fulltext_index_no_dba_preset 66_sanity-check-stylesheets_shebang 67_patchset-2012-10-10 +68_lock_transaction_updates +69_remove_unused_authenticate_method