[Rt-commit] rt branch, 4.0-trunk, updated. rt-3.9.7-1213-gf45c11c

Kevin Falcone falcone at bestpractical.com
Wed Jan 19 19:22:36 EST 2011


The branch, 4.0-trunk has been updated
       via  f45c11c4aa056747be0d1d01fac9c8f517f5e407 (commit)
       via  bc109639335ce1ab558b851c0f92574ffd540bee (commit)
       via  d18c3f1aa0722c58562071237c982747ce0e549f (commit)
       via  f9e719ff7a8dac1bedd8e13d6055eef2dc8792a2 (commit)
       via  94c3a0ac84e1b57a8fc3e214ca12934a8fb18fe3 (commit)
       via  c4d6bdc2ba65b646368cb4677bbfb81f24a41dd9 (commit)
       via  64119d859b3a14eee9b4509ee874484b2b952b36 (commit)
       via  24a4b291081b3538a79eb19f34f763d9fb3613a2 (commit)
       via  efee183c9cd169b9f0383b468d34b14d25c92b70 (commit)
       via  115943103bbf5693f9aba21e97b722d17025990a (commit)
      from  936afec9c1506872628cf8248551871fb4299771 (commit)

Summary of changes:
 .gitignore                          |    1 +
 configure.ac                        |    1 +
 docs/UPGRADING-3.8                  |   10 ++++
 etc/schema.Oracle                   |    2 +-
 etc/schema.Pg                       |    2 +-
 etc/schema.SQLite                   |    2 +-
 etc/schema.mysql                    |    2 +-
 etc/upgrade/4.0.0rc4/schema.Oracle  |    1 +
 etc/upgrade/4.0.0rc4/schema.Pg      |    1 +
 etc/upgrade/4.0.0rc4/schema.mysql   |    1 +
 etc/upgrade/vulnerable-passwords.in |   93 +++++++++++++++++++++++++++++++++
 lib/RT/User.pm                      |   98 ++++++++++++++++++++--------------
 sbin/rt-test-dependencies.in        |    1 +
 t/api/password-types.t              |   41 +++++++++++++++
 14 files changed, 212 insertions(+), 44 deletions(-)
 create mode 100644 etc/upgrade/4.0.0rc4/schema.Oracle
 create mode 100644 etc/upgrade/4.0.0rc4/schema.Pg
 create mode 100644 etc/upgrade/4.0.0rc4/schema.mysql
 create mode 100755 etc/upgrade/vulnerable-passwords.in
 create mode 100644 t/api/password-types.t

- Log -----------------------------------------------------------------
commit 115943103bbf5693f9aba21e97b722d17025990a
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Dec 15 01:00:05 2010 -0500

    Increase the size of the password field to 256 characters
    
    The existing size of 40 characters is insufficient to store passwords
    with any sort of security these days.  256 bytes should be large
    enough to provide room to grow in.

diff --git a/etc/schema.Oracle b/etc/schema.Oracle
index d60383b..4bcae6c 100755
--- a/etc/schema.Oracle
+++ b/etc/schema.Oracle
@@ -203,7 +203,7 @@ CREATE TABLE Users (
 		CONSTRAINT Users_Key PRIMARY KEY,
   	Name 			VARCHAR2(200) CONSTRAINT Users_Name_Unique 
 		unique  NOT NULL,
-  	Password 		VARCHAR2(40),
+  	Password 		VARCHAR2(256),
   	AuthToken 		VARCHAR2(16),
   	Comments 		CLOB,
   	Signature 		CLOB,
diff --git a/etc/schema.Pg b/etc/schema.Pg
index a93ef55..565f76b 100755
--- a/etc/schema.Pg
+++ b/etc/schema.Pg
@@ -339,7 +339,7 @@ CREATE SEQUENCE users_id_seq;
 CREATE TABLE Users (
   id INTEGER DEFAULT nextval('users_id_seq'),
   Name varchar(200) NOT NULL  ,
-  Password varchar(40) NULL  ,
+  Password varchar(256) NULL  ,
   AuthToken varchar(16) NULL  ,
   Comments text NULL  ,
   Signature text NULL  ,
diff --git a/etc/schema.SQLite b/etc/schema.SQLite
index 7c838cd..138971c 100755
--- a/etc/schema.SQLite
+++ b/etc/schema.SQLite
@@ -220,7 +220,7 @@ create table CachedGroupMembers (
 CREATE TABLE Users (
   id INTEGER ,
   Name varchar(200) NOT NULL  ,
-  Password varchar(40) NULL  ,
+  Password varchar(256) NULL  ,
   AuthToken varchar(16) NULL  ,
   Comments blob NULL  ,
   Signature blob NULL  ,
diff --git a/etc/schema.mysql b/etc/schema.mysql
index 8fcd3ec..c87f241 100755
--- a/etc/schema.mysql
+++ b/etc/schema.mysql
@@ -211,7 +211,7 @@ CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (MemberId, ImmediateParen
 CREATE TABLE Users (
   id INTEGER NOT NULL  AUTO_INCREMENT,
   Name varchar(200) NOT NULL  ,
-  Password VARBINARY(40) NULL  ,
+  Password VARCHAR(256) NULL  ,
   AuthToken VARCHAR(16) CHARACTER SET ascii NULL  ,
   Comments TEXT NULL  ,
   Signature TEXT NULL  ,
diff --git a/etc/upgrade/3.9.9/schema.Oracle b/etc/upgrade/3.9.9/schema.Oracle
new file mode 100644
index 0000000..0df9d65
--- /dev/null
+++ b/etc/upgrade/3.9.9/schema.Oracle
@@ -0,0 +1 @@
+ALTER TABLE Users MODIFY Password VARCHAR2(256);
diff --git a/etc/upgrade/3.9.9/schema.Pg b/etc/upgrade/3.9.9/schema.Pg
new file mode 100644
index 0000000..7280810
--- /dev/null
+++ b/etc/upgrade/3.9.9/schema.Pg
@@ -0,0 +1 @@
+ALTER TABLE Users ALTER Password TYPE varchar(256);
diff --git a/etc/upgrade/3.9.9/schema.mysql b/etc/upgrade/3.9.9/schema.mysql
new file mode 100644
index 0000000..2f562bd
--- /dev/null
+++ b/etc/upgrade/3.9.9/schema.mysql
@@ -0,0 +1 @@
+ALTER TABLE Users MODIFY Password varchar(256);
diff --git a/lib/RT/User.pm b/lib/RT/User.pm
index 051b8c4..03d98dd 100644
--- a/lib/RT/User.pm
+++ b/lib/RT/User.pm
@@ -1567,7 +1567,7 @@ sub BasicColumns {
 Create takes a hash of values and creates a row in the database:
 
   varchar(200) 'Name'.
-  varbinary(40) 'Password'.
+  varbinary(256) 'Password'.
   varchar(16) 'AuthToken'.
   text 'Comments'.
   text 'Signature'.
@@ -1632,7 +1632,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =head2 Password
 
 Returns the current value of Password. 
-(In the database, Password is stored as varbinary(40).)
+(In the database, Password is stored as varchar(256).)
 
 
 
@@ -1641,7 +1641,7 @@ Returns the current value of Password.
 
 Set Password to VALUE. 
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, Password will be stored as a varbinary(40).)
+(In the database, Password will be stored as a varchar(256).)
 
 
 =cut
@@ -2196,7 +2196,7 @@ sub _CoreAccessible {
         Name => 
         {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         Password => 
-        {read => 1, write => 1, sql_type => 12, length => 40,  is_blob => 0,  is_numeric => 0,  type => 'varbinary(40)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 256,  is_blob => 0,  is_numeric => 0,  type => 'varchar(256)', default => ''},
         AuthToken => 
         {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         Comments => 

commit efee183c9cd169b9f0383b468d34b14d25c92b70
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Dec 15 01:01:56 2010 -0500

    Move to a SHA-512 based password authentication scheme
    
    This continues to support all four previous password storage formats
    that RT had, while changing the default format to a more secure salted
    SHA-512 hash, which is approved by NIST.  More importly, the previous
    MD5-based implementation failed to use a salt, making rainbow table
    attacks on leaked RT databases nearly trivial.  The use of a 16-byte
    salt should make such attacks infeasable in the future.
    
    At the same time, the format has been extended to explicitly state the
    password storage format, for better backwards and forwards
    compatability.  Similar to the format of passwords on unix, RT uses:
       !method!salt!hash

diff --git a/lib/RT/User.pm b/lib/RT/User.pm
index 03d98dd..78e6179 100644
--- a/lib/RT/User.pm
+++ b/lib/RT/User.pm
@@ -76,6 +76,7 @@ sub Table {'Users'}
 
 
 
+use Digest::SHA;
 use Digest::MD5;
 use RT::Principals;
 use RT::ACE;
@@ -829,37 +830,36 @@ sub SetPassword {
 
 }
 
-=head3 _GeneratePassword PASSWORD
-
-returns an MD5 hash of the password passed in, in hexadecimal encoding.
-
-=cut
-
-sub _GeneratePassword {
+sub _GeneratePassword_sha512 {
     my $self = shift;
-    my $password = shift;
+    my ($password, $salt) = @_;
 
-    my $md5 = Digest::MD5->new();
-    $md5->add(encode_utf8($password));
-    return ($md5->hexdigest);
+    # Generate a 16-character base64 salt
+    unless ($salt) {
+        $salt = "";
+        $salt .= ("a".."z", "A".."Z","0".."9", "+", "/")[rand 64]
+            for 1..16;
+    }
 
+    my $sha = Digest::SHA->new(512);
+    $sha->add($salt);
+    $sha->add(encode_utf8($password));
+    return join("!", "", "sha512", $salt, $sha->b64digest);
 }
 
-=head3 _GeneratePasswordBase64 PASSWORD
+=head3 _GeneratePassword PASSWORD [, SALT]
 
-returns an MD5 hash of the password passed in, in base64 encoding
-(obsoleted now).
+Returns a string to store in the database.  This string takes the form:
 
-=cut
+   !method!salt!hash
 
-sub _GeneratePasswordBase64 {
-    my $self = shift;
-    my $password = shift;
+By default, the method is currently C<sha512>.
 
-    my $md5 = Digest::MD5->new();
-    $md5->add(encode_utf8($password));
-    return ($md5->b64digest);
+=cut
 
+sub _GeneratePassword {
+    my $self = shift;
+    return $self->_GeneratePassword_sha512(@_);
 }
 
 =head3 HasPassword
@@ -905,23 +905,41 @@ sub IsPassword {
         return(undef);
      }
 
-    # generate an md5 password
-    if ($self->_GeneratePassword($value) eq $self->__Value('Password')) {
-        return(1);
-    }
-
-    #  if it's a historical password we say ok.
-    if ($self->__Value('Password') eq crypt(encode_utf8($value), $self->__Value('Password'))
-        or $self->_GeneratePasswordBase64($value) eq $self->__Value('Password'))
-    {
-        # ...but upgrade the legacy password inplace.
-        $self->_Set(Field => 'Password', Value =>  $self->_GeneratePassword($value) );
-        return(1);
+    my $stored = $self->__Value('Password');
+    if ($stored =~ /^!/) {
+        # If it's a new-style (>= RT 4.0) password, it starts with a '!'
+        my (undef, $method, $salt, undef) = split /!/, $stored;
+        if ($method eq "sha512") {
+            return $self->_GeneratePassword_sha512($value, $salt) eq $stored;
+        } else {
+            $RT::Logger->warn("Unknown hash method $method");
+            return 0;
+        }
+    } elsif (length $stored == 40) {
+        # The truncated SHA256(salt,MD5(passwd)) form from 2010/12 is 40 characters long
+        my $hash = MIME::Base64::decode_base64($stored);
+        # The first 4 bytes are the salt, the rest is substr(SHA256,0,26)
+        my $salt = substr($hash, 0, 4, "");
+        return 0 unless substr(Digest::SHA::sha256($salt . Digest::MD5::md5($value)), 0, 26) eq $hash;
+    } elsif (length $stored == 32) {
+        # Hex nonsalted-md5
+        return 0 unless Digest::MD5::md5_hex(encode_utf8($value)) eq $stored;
+    } elsif (length $stored == 22) {
+        # Base64 nonsalted-md5
+        return 0 unless Digest::MD5::md5_base64(encode_utf8($value)) eq $stored;
+    } elsif (length $stored == 13) {
+        # crypt() output
+        return 0 unless crypt(encode_utf8($value), $stored) eq $stored;
+    } else {
+        $RT::Logger->warn("Unknown password form");
+        return 0;
     }
 
-    # no password check has succeeded. get out
-
-    return (undef);
+    # We got here by validating successfully, but with a legacy
+    # password form.  Update to the most recent form.
+    my $obj = $self->isa("RT::CurrentUser") ? $self->UserObj : $self;
+    $obj->_Set(Field => 'Password', Value =>  $self->_GeneratePassword($value) );
+    return 1;
 }
 
 sub CurrentUserRequireToSetPassword {

commit 24a4b291081b3538a79eb19f34f763d9fb3613a2
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Dec 15 10:37:40 2010 -0500

    Provide a tool to upgrade weak hashes to the new 40-char SHA-256 form

diff --git a/.gitignore b/.gitignore
index 63aabd8..7b74b55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ etc/upgrade/3.8-ical-extension
 etc/upgrade/split-out-cf-categories
 etc/upgrade/generate-rtaddressregexp
 etc/upgrade/upgrade-articles
+etc/upgrade/vulnerable-passwords
 lib/RT/Generated.pm
 Makefile
 t/data/gnupg/keyrings/random_seed
diff --git a/UPGRADING b/UPGRADING
index 9de47f6..014ce06 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -82,6 +82,16 @@ with
 *******
 UPGRADING FROM 3.8.8 and earlier - Changes:
 
+Previous versions of RT used a password hashing scheme which was too
+easy to reverse, which could allow attackers with read access to the
+RT database to possibly compromise users' passwords.  Even if RT does
+no password authentication itself, it may still store these weak
+password hashes -- using ExternalAuth does not guarantee that you are
+not vulnerable!  To upgrade stored passwords to a stronger hash, run:
+
+    perl etc/upgrade/vulnerable-passwords
+
+
 We've proved that it's possible to delete set of records
 from Transactions table without losing functionality. To delete
 record run the following script:
diff --git a/configure.ac b/configure.ac
index 12efb1a..ba4eb94 100755
--- a/configure.ac
+++ b/configure.ac
@@ -393,6 +393,7 @@ AC_CONFIG_FILES([
                  etc/upgrade/split-out-cf-categories
                  etc/upgrade/generate-rtaddressregexp
                  etc/upgrade/upgrade-articles
+                 etc/upgrade/vulnerable-passwords
                  sbin/rt-attributes-viewer
                  sbin/rt-session-viewer
                  sbin/rt-dump-metadata
diff --git a/etc/upgrade/vulnerable-passwords.in b/etc/upgrade/vulnerable-passwords.in
new file mode 100755
index 0000000..a12b80e
--- /dev/null
+++ b/etc/upgrade/vulnerable-passwords.in
@@ -0,0 +1,93 @@
+#!@PERL@
+
+use strict;
+use warnings;
+
+use lib "@LOCAL_LIB_PATH@";
+use lib "@RT_LIB_PATH@";
+
+use RT;
+RT::LoadConfig;
+RT::Init;
+
+$| = 1;
+
+use Getopt::Long;
+use Digest::SHA;
+my $fix;
+GetOptions("fix!" => \$fix);
+
+use RT::Users;
+my $users = RT::Users->new( $RT::SystemUser );
+$users->Limit(
+    FIELD => 'Password',
+    OPERATOR => 'IS NOT',
+    VALUE => 'NULL',
+    ENTRYAGGREGATOR => 'AND',
+);
+$users->Limit(
+    FIELD => 'Password',
+    OPERATOR => '!=',
+    VALUE => '*NO-PASSWORD*',
+    ENTRYAGGREGATOR => 'AND',
+);
+$users->Limit(
+    FIELD => 'Password',
+    OPERATOR => 'NOT STARTSWITH',
+    VALUE => '!',
+    ENTRYAGGREGATOR => 'AND',
+);
+push @{$users->{'restrictions'}{ "main.Password" }}, "AND", {
+    field => 'LENGTH(main.Password)',
+    op => '<',
+    value => '40',
+};
+
+my $count = $users->Count;
+if ($count == 0) {
+    print "No users with unsalted or weak cryptography found.\n";
+    exit 0;
+}
+
+if ($fix) {
+    print "Upgrading $count users...\n";
+    while (my $u = $users->Next) {
+        my $stored = $u->__Value("Password");
+        my $raw;
+        if (length $stored == 32) {
+            $raw = pack("H*",$stored);
+        } elsif (length $stored == 22) {
+            $raw = MIME::Base64::decode_base64($stored);
+        } elsif (length $stored == 13) {
+            printf "%20s => Old crypt() format, cannot upgrade\n", $u->Name;
+        } else {
+            printf "%20s => Unknown password format!\n", $u->Name;
+        }
+        next unless $raw;
+
+        my $salt = pack("C4",map{int rand(256)} 1..4);
+        my $sha = Digest::SHA::sha256(
+            $salt . $raw
+        );
+        $u->_Set(
+            Field => "Password",
+            Value => MIME::Base64::encode_base64(
+                $salt . substr($sha,0,26)),
+        );
+    }
+    print "Done.\n";
+    exit 0;
+} else {
+    if ($count < 20) {
+        print "$count users found with unsalted or weak-cryptography passwords:\n";
+        print "      Id | Name\n", "-"x9, "+", "-"x9, "\n";
+        while (my $u = $users->Next) {
+            printf "%8d | %s\n", $u->Id, $u->Name;
+        }
+    } else {
+        print "$count users found with unsalted or weak-cryptography passwords\n";
+    }
+
+    print "\n", "Run again with --fix to upgrade.\n";
+    exit 1;
+}

commit 64119d859b3a14eee9b4509ee874484b2b952b36
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Mon Jan 3 21:28:09 2011 -0500

    Clarify a comment explaining apparent byte length disagreement

diff --git a/lib/RT/User.pm b/lib/RT/User.pm
index 78e6179..40855bd 100644
--- a/lib/RT/User.pm
+++ b/lib/RT/User.pm
@@ -918,7 +918,7 @@ sub IsPassword {
     } elsif (length $stored == 40) {
         # The truncated SHA256(salt,MD5(passwd)) form from 2010/12 is 40 characters long
         my $hash = MIME::Base64::decode_base64($stored);
-        # The first 4 bytes are the salt, the rest is substr(SHA256,0,26)
+        # Decoding yields 30 byes; first 4 are the salt, the rest are substr(SHA256,0,26)
         my $salt = substr($hash, 0, 4, "");
         return 0 unless substr(Digest::SHA::sha256($salt . Digest::MD5::md5($value)), 0, 26) eq $hash;
     } elsif (length $stored == 32) {

commit c4d6bdc2ba65b646368cb4677bbfb81f24a41dd9
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Mon Jan 3 21:31:56 2011 -0500

    Ensure that we remove the trailing newline from base64
    
    Otherwise, this generates 41-character-long strings, which fail to be
    caught by our password-version-recognizing code.  This step worked
    transparently on RT 3.8 because DBIx::SearchBuilder truncated the
    string to 40 characters (the size of the column at the time) when
    inserting.

diff --git a/etc/upgrade/vulnerable-passwords.in b/etc/upgrade/vulnerable-passwords.in
index a12b80e..c28d2b8 100755
--- a/etc/upgrade/vulnerable-passwords.in
+++ b/etc/upgrade/vulnerable-passwords.in
@@ -72,7 +72,7 @@ if ($fix) {
         $u->_Set(
             Field => "Password",
             Value => MIME::Base64::encode_base64(
-                $salt . substr($sha,0,26)),
+                $salt . substr($sha,0,26), ""),
         );
     }
     print "Done.\n";

commit 94c3a0ac84e1b57a8fc3e214ca12934a8fb18fe3
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Mon Jan 3 21:28:51 2011 -0500

    Add tests for the various password forms, and automatic upgrading

diff --git a/t/api/password-types.t b/t/api/password-types.t
new file mode 100644
index 0000000..5f253d5
--- /dev/null
+++ b/t/api/password-types.t
@@ -0,0 +1,41 @@
+#!/usr/bin/perl -w
+use strict;
+use warnings;
+
+use RT::Test;
+use Digest::MD5;
+
+my $default = "sha512";
+
+my $root = RT::User->new(RT->SystemUser);
+$root->Load("root");
+
+# Salted SHA-512 (default)
+my $old = $root->__Value("Password");
+like($old, qr/^\!$default\!/, "Stored as salted $default");
+ok($root->IsPassword("password"));
+is($root->__Value("Password"), $old, "Unchanged after password check");
+
+# Crypt
+$root->_Set( Field => "Password", Value => crypt("something", "salt"));
+ok($root->IsPassword("something"), "crypt()ed password works");
+like($root->__Value("Password"), qr/^\!$default\!/, "And is now upgraded to salted $default");
+
+# MD5, hex
+$root->_Set( Field => "Password", Value => Digest::MD5::md5_hex("changed"));
+ok($root->IsPassword("changed"), "Unsalted MD5 hex works");
+like($root->__Value("Password"), qr/^\!$default\!/, "And is now upgraded to salted $default");
+
+# MD5, base64
+$root->_Set( Field => "Password", Value => Digest::MD5::md5_base64("new"));
+ok($root->IsPassword("new"), "Unsalted MD5 base64 works");
+like($root->__Value("Password"), qr/^\!$default\!/, "And is now upgraded to salted $default");
+
+# Salted truncated SHA-256
+my $trunc = MIME::Base64::encode_base64(
+    "salt" . substr(Digest::SHA::sha256("salt".Digest::MD5::md5("secret")),0,26),
+    ""
+);
+$root->_Set( Field => "Password", Value => $trunc);
+ok($root->IsPassword("secret"), "Unsalted MD5 base64 works");
+like($root->__Value("Password"), qr/^\!$default\!/, "And is now upgraded to salted $default");

commit f9e719ff7a8dac1bedd8e13d6055eef2dc8792a2
Merge: 94c3a0a 3f5cc6e
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Tue Jan 4 14:06:14 2011 -0500

    Merge branch '4.0-trunk' into salted-passwords
    
    Conflicts:
    	UPGRADING

diff --cc docs/UPGRADING-3.8
index 0000000,d2bb751..55d5540
mode 000000,100644..100644
--- a/docs/UPGRADING-3.8
+++ b/docs/UPGRADING-3.8
@@@ -1,0 -1,159 +1,169 @@@
+ UPGRADING FROM 3.8.8 and earlier - Changes:
+ 
++Previous versions of RT used a password hashing scheme which was too
++easy to reverse, which could allow attackers with read access to the
++RT database to possibly compromise users' passwords.  Even if RT does
++no password authentication itself, it may still store these weak
++password hashes -- using ExternalAuth does not guarantee that you are
++not vulnerable!  To upgrade stored passwords to a stronger hash, run:
++
++    perl etc/upgrade/vulnerable-passwords
++
++
+ We've proved that it's possible to delete set of records
+ from Transactions table without losing functionality. To delete
+ records run the following script:
+ 
+     perl -I /opt/rt4/local/lib -I /opt/rt4/lib etc/upgrade/shrink_transactions_table.pl
+ 
+ If you chose not to run the shrink_cgm_table.pl script when you upgraded to 3.8,
+ you should read more about it below and run it at this point.
+ 
+ The default for $MessageBoxWrap is now SOFT and $MessageBoxWidth is now unset
+ by default.  This means the message box will expand to fill all the available
+ width.  $MessageBoxWrap is also overridable by the user now.  These changes
+ accommodate the new default two column layout for ticket create and update
+ pages.  You may turn this layout off by setting $UseSideBySideLayout to 0.  To
+ retain the original behavior, set $MessageBoxWrap to HARD and $MessageBoxWidth
+ to 72.
+ 
+ UPGRADING FROM 3.8.7 and earlier - Changes:
+ 
+ RT's ChartFont option has been changed from a string to a hash which
+ lets you specify per-language fonts. RT now comes with a better default
+ font for charts, too.
+ 
+ You should either update your 'ChartFont' option to match the new format
+ or consider trying the new default
+ 
+ RT now gives you more precise control over the order in which custom fields
+ are displayed.  This change requires some small changes to your currently saved
+ custom field orders.
+ 
+ RT will automatically clean up your existing custom fields when you run:
+ 
+ 
+   /opt/rt4/sbin/rt-setup-database --dba root --prompt-for-dba-password --action upgrade
+ 
+ After that cleanup, you should make sure that custom fields are ordered in
+ a way that you and your users find pleasing.
+ 
+ UPGRADING FROM 3.8.6 and earlier - Changes:
+ 
+ For MySQL and Oracle users:
+ If you upgraded from a version of RT earlier than 3.7.81 you should
+ already have a CachedGroupMembers3 index on your CachedGroupMembers table.
+ If you did a clean install of RT somewhere in the 3.8 release series, you 
+ most likely don't have this index.  You can add it manually with
+ 
+   CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (MemberId, ImmediateParentId);
+ 
+ UPGRADING FROM 3.8.5 and earlier - Changes:
+ 
+ You can now forward an entire Ticket history (in addition to specific transactions)
+ but this requires a new Template called forward ticket.  This template will be added
+ when you run.
+ 
+ /opt/rt4/sbin/rt-setup-database --dba root --prompt-for-dba-password --action upgrade
+ 
+ Custom fields with categories can optionally be split out into
+ hierarchical custom fields.  If you wish to convert your old
+ category-based custom fields, run:
+ 
+     perl etc/upgrade/split-out-cf-categories
+ 
+ It will prompt you for each custom field with categories that it
+ finds, and the name of the custom field to create to store the
+ categories.
+ 
+ If you were using the LocalizedDateTime RT::Date formatter from code
+ and passing a DateFormat or TimeFormat argument, you need to switch from 
+ the strftime methods to the cldr methods (ie full_date_format becomes date_format_full)
+ You may have done this from your RT_SiteConfig.pm by using
+ Set($DateTimeFormat, { Format => 'LocalizedDateTime', DateFormat => 'medium_date_format' );
+ 
+ UPGRADING FROM 3.8.3 and earlier - Changes:
+ 
+ Arguments to the NotifyGroup Scrip Action need
+ to be corrected in the database using 
+ 
+ /opt/rt4/sbin/rt-setup-database --dba root --prompt-for-dba-password --action upgrade
+ 
+ 
+ UPGRADING FROM 3.8.2 and earlier - Changes:
+ 
+ New scrip condition 'On Reject'.
+ 
+ UPGRADING FROM 3.8.1 and earlier - Changes:
+ 
+ = Oracle configuration =
+ 
+ $DatabaseName is used as SID, so RT can connect without environment variables
+ or tnsnames.ora file. Because of this change your RT instance may loose ability
+ to connect to your DB, you have to update options and restart your web server.
+ Example configuration:
+ 
+     Set($DatabaseType, 'Oracle');
+     Set($DatabaseHost, '192.168.0.1');
+     # undefined port => will try both 1526 and 1521
+     Set($DatabasePort, undef);
+     # ORACLE SID
+     Set($DatabaseName, 'XE');
+     # user for RT in Oracle, RT's tables in his schema
+     Set($DatabaseUser, 'test');
+     # above user's password
+     Set($DatabasePassword, 'test');
+ 
+ = Rights changes =
+ 
+ Now, if you want any user to be able to access the Approvals tools (a.k.a.  the
+ Approvals tab), you must grant that user the "ShowApprovalsTab" right.
+ 
+ UPGRADING FROM 3.8.0 and earlier - Changes:
+ 
+ Searches for bookmarked tickets have been reimplemented and syntax has
+ been changed a little. Database upgrade script handles global 'Bookmarked Tickets'
+ search only. New Ticket SQL "id = '__Bookmarked__'" is more flexible than
+ old "__Bookmarks__". Old version is not valid Ticket SQL query, so people
+ can not use it in the query builder and as well admins couldn't not edit
+ format and other properties of the global saved search. Old version's been
+ left for backwards compatibility.
+ 
+ UPGRADING FROM 3.7.85 and earlier - Changes:
+ 
+ We've proved that it's possible to delete pretty big set of records
+ from CachedGroupMembers table without losing functionality. To delete
+ record run the following script.  If you don't run this, you may
+ occasionally see problems where RT miscounts users, particularly in the
+ chart functionality.
+ 
+     perl -I /opt/rt4/local/lib -I /opt/rt4/lib etc/upgrade/shrink_cgm_table.pl
+ 
+ After you run this, you'll have significantly reduced the number of
+ records in your CachedGroupMembers table and may need to tell your
+ database to refresh indexes/statistics.  Please consult your DBA for
+ specific instructions for your database.
+ 
+ UPGRADING FROM 3.7.81 and earlier - Changes:
+ 
+ RT::Extension::BrandedQueues has been integrated into core, so you MUST read
+ upgrading instructions docs/queue_subject_tag.pod EVEN IF you have not used
+ that extension.
+ 
+ RT::Action::LinearEscalate extension has been integrated into core,
+ so you MUST uninstall it before upgrading.
+ 
+ RT::Extension::iCal has been integrated into core, so you MUST uninstall
+ it before upgrading. In addition, you must run etc/upgrade/3.8-ical-extension
+ script to convert old data.
+ 
+ UPGRADING FROM 3.7.80 and earlier - Changes:
+ 
+ Added indexes to CachedGroupMembers for MySQL and Oracle.
+ If you have previously installed RTx-Shredder, you may already
+ have these indexes.  You can see the indexes by looking at
+ etc/upgrade/3.7.81/schema.*
+ 
+ These indexes may take a very long time to create.
+ 
+ 

commit d18c3f1aa0722c58562071237c982747ce0e549f
Merge: 936afec f9e719f
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Wed Jan 19 17:18:47 2011 -0500

    Merge branch '4.0/salted-passwords' into 4.0-trunk


commit bc109639335ce1ab558b851c0f92574ffd540bee
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Wed Jan 19 17:20:02 2011 -0500

    Put this in the correct versioned dir

diff --git a/etc/upgrade/3.9.9/schema.Oracle b/etc/upgrade/4.0.0rc4/schema.Oracle
similarity index 100%
rename from etc/upgrade/3.9.9/schema.Oracle
rename to etc/upgrade/4.0.0rc4/schema.Oracle
diff --git a/etc/upgrade/3.9.9/schema.Pg b/etc/upgrade/4.0.0rc4/schema.Pg
similarity index 100%
rename from etc/upgrade/3.9.9/schema.Pg
rename to etc/upgrade/4.0.0rc4/schema.Pg
diff --git a/etc/upgrade/3.9.9/schema.mysql b/etc/upgrade/4.0.0rc4/schema.mysql
similarity index 100%
rename from etc/upgrade/3.9.9/schema.mysql
rename to etc/upgrade/4.0.0rc4/schema.mysql

commit f45c11c4aa056747be0d1d01fac9c8f517f5e407
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Wed Jan 19 18:11:20 2011 -0500

    We need Digest::SHA to upgrade passwords, have people install it

diff --git a/sbin/rt-test-dependencies.in b/sbin/rt-test-dependencies.in
index 10fef43..5b2d2bf 100755
--- a/sbin/rt-test-dependencies.in
+++ b/sbin/rt-test-dependencies.in
@@ -177,6 +177,7 @@ DateTime 0.44
 DateTime::Locale 0.40
 Digest::base
 Digest::MD5 2.27
+Digest::SHA
 DBI 1.37
 Class::ReturnValue 0.40
 DBIx::SearchBuilder 1.59

-----------------------------------------------------------------------


More information about the Rt-commit mailing list