From 788e94b41f8124a05c6f25bf3084fcdaa36f4d63 Mon Sep 17 00:00:00 2001 From: "bbaetz%student.usyd.edu.au" <> Date: Mon, 4 Feb 2002 20:23:04 +0000 Subject: Bug 95732 - remove logincookies.cryptpassword, and invalidate cookies from the db when required instead. (Also fixes bug 58242 as a side effect) r=myk, kiko --- CGI.pl | 5 ++--- checksetup.pl | 24 +++++++++++++++++++++++- editusers.cgi | 8 ++++++-- globals.pl | 13 +++++++++++++ relogin.cgi | 19 +++++++++++++++++++ token.cgi | 2 ++ userprefs.cgi | 2 ++ 7 files changed, 67 insertions(+), 6 deletions(-) diff --git a/CGI.pl b/CGI.pl index f99013e25..d1a274680 100644 --- a/CGI.pl +++ b/CGI.pl @@ -689,8 +689,7 @@ sub quietly_check_login() { "profiles.login_name, " . "profiles.login_name = " . SqlQuote($::COOKIE{"Bugzilla_login"}) . - " AND profiles.cryptpassword = logincookies.cryptpassword " . - "AND logincookies.hostname = " . + " AND logincookies.hostname = " . SqlQuote($ENV{"REMOTE_HOST"}) . ", profiles.disabledtext " . " FROM profiles, logincookies WHERE logincookies.cookie = " . @@ -979,7 +978,7 @@ sub confirm_login { if (!defined $ENV{'REMOTE_HOST'}) { $ENV{'REMOTE_HOST'} = $ENV{'REMOTE_ADDR'}; } - SendSQL("insert into logincookies (userid,cryptpassword,hostname) values (@{[DBNameToIdAndCheck($enteredlogin)]}, @{[SqlQuote($realcryptpwd)]}, @{[SqlQuote($ENV{'REMOTE_HOST'})]})"); + SendSQL("insert into logincookies (userid,hostname) values (@{[DBNameToIdAndCheck($enteredlogin)]}, @{[SqlQuote($ENV{'REMOTE_HOST'})]})"); SendSQL("select LAST_INSERT_ID()"); my $logincookie = FetchOneColumn(); diff --git a/checksetup.pl b/checksetup.pl index 125b18a6c..71e501ffb 100755 --- a/checksetup.pl +++ b/checksetup.pl @@ -1082,7 +1082,6 @@ $table{groups} = $table{logincookies} = 'cookie mediumint not null auto_increment primary key, userid mediumint not null, - cryptpassword varchar(34), hostname varchar(128), lastused timestamp, @@ -2596,6 +2595,29 @@ AddField("bugs", "cclist_accessible", "tinyint not null default 1"); # using the attachment manager can record changes to attachments. AddField("bugs_activity", "attach_id", "mediumint null"); +# 2001-01-17 bbaetz@student.usyd.edu.au bug 95732 +# Remove logincookies.cryptpassword, and delete entries which become +# invalid +if (GetFieldDef("logincookies", "cryptpassword")) { + # We need to delete any cookies which are invalid, before dropping the + # column + + print "Removing invalid login cookies...\n"; + + # mysql doesn't support DELETE with multi-table queries, so we have + # to iterate + my $sth = $dbh->prepare("SELECT cookie FROM logincookies, profiles " . + "WHERE logincookies.cryptpassword != " . + "profiles.cryptpassword AND " . + "logincookies.userid = profiles.userid"); + $sth->execute(); + while (my ($cookie) = $sth->fetchrow_array()) { + $dbh->do("DELETE FROM logincookies WHERE cookie = $cookie"); + } + + DropField("logincookies", "cryptpassword"); +} + # If you had to change the --TABLE-- definition in any way, then add your # differential change code *** A B O V E *** this comment. # diff --git a/editusers.cgi b/editusers.cgi index a2a6ee51b..ad00dd9ae 100755 --- a/editusers.cgi +++ b/editusers.cgi @@ -808,6 +808,11 @@ if ($action eq 'update') { SendSQL("UPDATE profiles SET cryptpassword = $cryptpassword WHERE login_name = $loginname"); + SendSQL("SELECT userid + FROM profiles + WHERE login_name=" . SqlQuote($userold)); + my $userid = FetchOneColumn(); + InvalidateLogins($userid); print "Updated password.
\n"; } else { print "Did not update password: $passworderror
\n"; @@ -827,8 +832,7 @@ if ($action eq 'update') { FROM profiles WHERE login_name=" . SqlQuote($userold)); my $userid = FetchOneColumn(); - SendSQL("DELETE FROM logincookies - WHERE userid=" . $userid); + InvalidateLogins($userid); print "Updated disabled text.
\n"; } if ($editall && $user ne $userold) { diff --git a/globals.pl b/globals.pl index cc05ae345..845e6ed9a 100644 --- a/globals.pl +++ b/globals.pl @@ -706,6 +706,19 @@ sub InsertNewUser { return $password; } +# Removes all entries from logincookies for $userid, except for the +# optional $keep, which refers the logincookies.cookie primary key. +# (This is useful so that a user changing their password stays logged in) +sub InvalidateLogins { + my ($userid, $keep) = @_; + + my $remove = "DELETE FROM logincookies WHERE userid = $userid"; + if (defined $keep) { + $remove .= " AND cookie != " . SqlQuote($keep); + } + SendSQL($remove); +} + sub GenerateRandomPassword { my ($size) = @_; diff --git a/relogin.cgi b/relogin.cgi index 091a96e8d..a0ec4f105 100755 --- a/relogin.cgi +++ b/relogin.cgi @@ -29,6 +29,25 @@ use lib qw(.); require "CGI.pl"; +# We don't want to remove a random logincookie from the db, so +# call quietly_check_login. If we're logged in after this, then +# the logincookie must be correct + +ConnectToDatabase(); +quietly_check_login(); + +if ($::userid) { + # Even though we know the userid must match, we still check it in the + # SQL as a sanity check, since there is no locking here, and if + # the user logged out from two machines simulataniously, while someone + # else logged in and got the same cookie, we could be logging the + # other user out here. Yes, this is very very very unlikely, but why + # take chances? - bbaetz + SendSQL("DELETE FROM logincookies WHERE cookie = " . + SqlQuote($::COOKIE{"Bugzilla_logincookie"}) . + "AND userid = $::userid"); +} + my $cookiepath = Param("cookiepath"); print "Set-Cookie: Bugzilla_login= ; path=$cookiepath; expires=Sun, 30-Jun-80 00:00:00 GMT Set-Cookie: Bugzilla_logincookie= ; path=$cookiepath; expires=Sun, 30-Jun-80 00:00:00 GMT diff --git a/token.cgi b/token.cgi index 81ae29629..7e20d7483 100755 --- a/token.cgi +++ b/token.cgi @@ -227,6 +227,8 @@ sub changePassword { SendSQL("DELETE FROM tokens WHERE token = $::quotedtoken"); SendSQL("UNLOCK TABLES"); + InvalidateLogins($userid); + # Return HTTP response headers. print "Content-Type: text/html\n\n"; diff --git a/userprefs.cgi b/userprefs.cgi index 531d57c0e..eb823326a 100755 --- a/userprefs.cgi +++ b/userprefs.cgi @@ -171,6 +171,8 @@ sub SaveAccount { SendSQL("UPDATE profiles SET cryptpassword = $cryptedpassword WHERE userid = $userid"); + # Invalidate all logins except for the current one + InvalidateLogins($userid, $::COOKIE{"Bugzilla_logincookie"}); } SendSQL("UPDATE profiles SET " . "realname = " . SqlQuote(trim($::FORM{'realname'})) . -- cgit v1.2.3-24-g4f1b