diff options
author | 2011-02-20 13:34:40 +0100 | |
---|---|---|
committer | 2011-02-20 13:34:40 +0100 | |
commit | 28a94bd2cd6da786d61c3ca5df7e3c662608bfc3 (patch) | |
tree | 045f2a849333ed1be18bc0143d23581c0d49f3c0 /relogin.cgi | |
download | bugzilla-28a94bd2cd6da786d61c3ca5df7e3c662608bfc3.tar.gz bugzilla-28a94bd2cd6da786d61c3ca5df7e3c662608bfc3.tar.bz2 bugzilla-28a94bd2cd6da786d61c3ca5df7e3c662608bfc3.zip |
Bugzilla 4.0 vanilla
Diffstat (limited to 'relogin.cgi')
-rwxr-xr-x | relogin.cgi | 203 |
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()); |