aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Ruppert <idl0r@gentoo.org>2011-02-20 13:34:40 +0100
committerChristian Ruppert <idl0r@gentoo.org>2011-02-20 13:34:40 +0100
commit28a94bd2cd6da786d61c3ca5df7e3c662608bfc3 (patch)
tree045f2a849333ed1be18bc0143d23581c0d49f3c0 /relogin.cgi
downloadbugzilla-28a94bd2cd6da786d61c3ca5df7e3c662608bfc3.tar.gz
bugzilla-28a94bd2cd6da786d61c3ca5df7e3c662608bfc3.tar.bz2
bugzilla-28a94bd2cd6da786d61c3ca5df7e3c662608bfc3.zip
Bugzilla 4.0 vanilla
Diffstat (limited to 'relogin.cgi')
-rwxr-xr-xrelogin.cgi203
1 files changed, 203 insertions, 0 deletions
diff --git a/relogin.cgi b/relogin.cgi
new file mode 100755
index 000000000..0e04b1bdc
--- /dev/null
+++ b/relogin.cgi
@@ -0,0 +1,203 @@
+#!/usr/bin/perl -wT
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# The Initial Developer of the Original Code is Netscape Communications
+# Corporation. Portions created by Netscape are
+# Copyright (C) 1998 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s): Terry Weissman <terry@mozilla.org>
+# Gervase Markham <gerv@gerv.net>
+# A. Karl Kornel <karl@kornel.name>
+
+use strict;
+use lib qw(. lib);
+
+use Bugzilla;
+use Bugzilla::Mailer;
+use Bugzilla::Constants;
+use Bugzilla::Error;
+use Bugzilla::Token;
+use Bugzilla::User;
+use Bugzilla::Util;
+use Date::Format;
+
+my $template = Bugzilla->template;
+my $cgi = Bugzilla->cgi;
+
+my $action = $cgi->param('action') || '';
+
+my $vars = {};
+my $target;
+
+if (!$action) {
+ # redirect to index.cgi if no action is defined.
+ print $cgi->redirect(correct_urlbase() . 'index.cgi');
+}
+# prepare-sudo: Display the sudo information & login page
+elsif ($action eq 'prepare-sudo') {
+ # We must have a logged-in user to do this
+ # That user must be in the 'bz_sudoers' group
+ my $user = Bugzilla->login(LOGIN_REQUIRED);
+ unless ($user->in_group('bz_sudoers')) {
+ ThrowUserError('auth_failure', { group => 'bz_sudoers',
+ action => 'begin',
+ object => 'sudo_session' }
+ );
+ }
+
+ # Do not try to start a new session if one is already in progress!
+ if (defined(Bugzilla->sudoer)) {
+ ThrowUserError('sudo_in_progress', { target => $user->login });
+ }
+
+ # Keep a temporary record of the user visiting this page
+ $vars->{'token'} = issue_session_token('sudo_prepared');
+
+ # Show the sudo page
+ $vars->{'target_login_default'} = $cgi->param('target_login');
+ $vars->{'reason_default'} = $cgi->param('reason');
+ $target = 'admin/sudo.html.tmpl';
+}
+# begin-sudo: Confirm login and start sudo session
+elsif ($action eq 'begin-sudo') {
+ # We must be sure that the user is authenticating by providing a login
+ # and password.
+ # We only need to do this for authentication methods that involve Bugzilla
+ # directly obtaining a login (i.e. normal CGI login), as opposed to other
+ # methods (like Environment vars login).
+
+ # First, record if Bugzilla_login and Bugzilla_password were provided
+ my $credentials_provided;
+ if (defined($cgi->param('Bugzilla_login'))
+ && defined($cgi->param('Bugzilla_password')))
+ {
+ $credentials_provided = 1;
+ }
+
+ # Next, log in the user
+ my $user = Bugzilla->login(LOGIN_REQUIRED);
+
+ # At this point, the user is logged in. However, if they used a method
+ # where they could have provided a username/password (i.e. CGI), but they
+ # did not provide a username/password, then throw an error.
+ if ($user->authorizer->can_login && !$credentials_provided) {
+ ThrowUserError('sudo_password_required',
+ { target_login => $cgi->param('target_login'),
+ reason => $cgi->param('reason')});
+ }
+
+ # The user must be in the 'bz_sudoers' group
+ unless ($user->in_group('bz_sudoers')) {
+ ThrowUserError('auth_failure', { group => 'bz_sudoers',
+ action => 'begin',
+ object => 'sudo_session' }
+ );
+ }
+
+ # Do not try to start a new session if one is already in progress!
+ if (defined(Bugzilla->sudoer)) {
+ ThrowUserError('sudo_in_progress', { target => $user->login });
+ }
+
+ # Did the user actually go trough the 'sudo-prepare' action? Do some
+ # checks on the token the action should have left.
+ my ($token_user, $token_timestamp, $token_data) =
+ Bugzilla::Token::GetTokenData($cgi->param('token'));
+ unless (defined($token_user)
+ && defined($token_data)
+ && ($token_user == $user->id)
+ && ($token_data eq 'sudo_prepared'))
+ {
+ ThrowUserError('sudo_preparation_required',
+ { target_login => scalar $cgi->param('target_login'),
+ reason => scalar $cgi->param('reason')});
+ }
+ delete_token($cgi->param('token'));
+
+ # Get & verify the target user (the user who we will be impersonating)
+ my $target_user =
+ new Bugzilla::User({ name => $cgi->param('target_login') });
+ unless (defined($target_user)
+ && $target_user->id
+ && $user->can_see_user($target_user))
+ {
+ ThrowUserError('user_match_failed',
+ { 'name' => $cgi->param('target_login') }
+ );
+ }
+ if ($target_user->in_group('bz_sudo_protect')) {
+ ThrowUserError('sudo_protected', { login => $target_user->login });
+ }
+
+ # If we have a reason passed in, keep it under 200 characters
+ my $reason = $cgi->param('reason') || '';
+ $reason = substr($reason, $[, 200);
+
+ # Calculate the session expiry time (T + 6 hours)
+ my $time_string = time2str('%a, %d-%b-%Y %T %Z', time + MAX_SUDO_TOKEN_AGE, 'GMT');
+
+ # For future sessions, store the unique ID of the target user
+ my $token = Bugzilla::Token::_create_token($user->id, 'sudo', $target_user->id);
+ $cgi->send_cookie('-name' => 'sudo',
+ '-expires' => $time_string,
+ '-value' => $token
+ );
+
+ # For the present, change the values of Bugzilla::user & Bugzilla::sudoer
+ Bugzilla->sudo_request($target_user, $user);
+
+ # NOTE: If you want to log the start of an sudo session, do it here.
+
+ # Go ahead and send out the message now
+ my $message;
+ my $mail_template = Bugzilla->template_inner($target_user->settings->{'lang'}->{'value'});
+ $mail_template->process('email/sudo.txt.tmpl', { reason => $reason }, \$message);
+ MessageToMTA($message);
+
+ $vars->{'message'} = 'sudo_started';
+ $vars->{'target'} = $target_user->login;
+ $target = 'global/message.html.tmpl';
+}
+# end-sudo: End the current sudo session (if one is in progress)
+elsif ($action eq 'end-sudo') {
+ # Regardless of our state, delete the sudo cookie if it exists
+ my $token = $cgi->cookie('sudo');
+ $cgi->remove_cookie('sudo');
+
+ # Are we in an sudo session?
+ Bugzilla->login(LOGIN_OPTIONAL);
+ my $sudoer = Bugzilla->sudoer;
+ if (defined($sudoer)) {
+ Bugzilla->sudo_request($sudoer, undef);
+ }
+ # Now that the session is over, remove the token from the DB.
+ delete_token($token);
+
+ # NOTE: If you want to log the end of an sudo session, so it here.
+
+ $vars->{'message'} = 'sudo_ended';
+ $target = 'global/message.html.tmpl';
+}
+# No valid action found
+else {
+ Bugzilla->login(LOGIN_OPTIONAL);
+ ThrowUserError('unknown_action', {action => $action});
+}
+
+# Display the template
+print $cgi->header();
+$template->process($target, $vars)
+ || ThrowTemplateError($template->error());