RSS

(root)/bmo/4.2 : /relogin.cgi (revision 8095)

To get this branch, use:
bzr branch /bmo/4.2
Line Revision Contents
1 2107
#!/usr/bin/perl -wT
2 47
# -*- Mode: perl; indent-tabs-mode: nil -*-
3 1
#
4 371
# The contents of this file are subject to the Mozilla Public
5
# License Version 1.1 (the "License"); you may not use this file
6
# except in compliance with the License. You may obtain a copy of
7
# the License at http://www.mozilla.org/MPL/
8
#
9
# Software distributed under the License is distributed on an "AS
10
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11
# implied. See the License for the specific language governing
12
# rights and limitations under the License.
13
#
14 1
# The Original Code is the Bugzilla Bug Tracking System.
15 371
#
16 1
# The Initial Developer of the Original Code is Netscape Communications
17 371
# Corporation. Portions created by Netscape are
18
# Copyright (C) 1998 Netscape Communications Corporation. All
19
# Rights Reserved.
20
#
21 1
# Contributor(s): Terry Weissman <terry@mozilla.org>
22 1302
#                 Gervase Markham <gerv@gerv.net>
23 3737
#                 A. Karl Kornel <karl@kornel.name>
24 1
25 47
use strict;
26 5304
use lib qw(. lib);
27 3795
28 3582
use Bugzilla;
29 4190
use Bugzilla::Mailer;
30 3590
use Bugzilla::Constants;
31 3582
use Bugzilla::Error;
32 3831
use Bugzilla::Token;
33 3737
use Bugzilla::User;
34
use Bugzilla::Util;
35
use Date::Format;
36 2352
37 3582
my $template = Bugzilla->template;
38 2161
my $cgi = Bugzilla->cgi;
39 3737
40 6562
my $action = $cgi->param('action') || '';
41 3737
42
my $vars = {};
43
my $target;
44
45 6562
if (!$action) {
46
    # redirect to index.cgi if no action is defined.
47
    print $cgi->redirect(correct_urlbase() . 'index.cgi');
48 7855
    exit;
49 6562
}
50 3831
# prepare-sudo: Display the sudo information & login page
51 6562
elsif ($action eq 'prepare-sudo') {
52 3737
    # We must have a logged-in user to do this
53
    # That user must be in the 'bz_sudoers' group
54
    my $user = Bugzilla->login(LOGIN_REQUIRED);
55
    unless ($user->in_group('bz_sudoers')) {
56
        ThrowUserError('auth_failure', {  group => 'bz_sudoers',
57
                                         action => 'begin',
58
                                         object => 'sudo_session' }
59
        );
60
    }
61
    
62
    # Do not try to start a new session if one is already in progress!
63
    if (defined(Bugzilla->sudoer)) {
64 3759
        ThrowUserError('sudo_in_progress', { target => $user->login });
65 3737
    }
66
67 3999
    # Keep a temporary record of the user visiting this page
68 4612
    $vars->{'token'} = issue_session_token('sudo_prepared');
69 3737
70
    # Show the sudo page
71 3831
    $vars->{'target_login_default'} = $cgi->param('target_login');
72
    $vars->{'reason_default'} = $cgi->param('reason');
73 3737
    $target = 'admin/sudo.html.tmpl';
74
}
75
# begin-sudo: Confirm login and start sudo session
76
elsif ($action eq 'begin-sudo') {
77 3831
    # We must be sure that the user is authenticating by providing a login
78
    # and password.
79
    # We only need to do this for authentication methods that involve Bugzilla 
80
    # directly obtaining a login (i.e. normal CGI login), as opposed to other 
81 4154
    # methods (like Environment vars login). 
82 3831
83
    # First, record if Bugzilla_login and Bugzilla_password were provided
84
    my $credentials_provided;
85
    if (defined($cgi->param('Bugzilla_login'))
86
        && defined($cgi->param('Bugzilla_password')))
87
    {
88
        $credentials_provided = 1;
89
    }
90
    
91
    # Next, log in the user
92 3737
    my $user = Bugzilla->login(LOGIN_REQUIRED);
93 3831
    
94
    # At this point, the user is logged in.  However, if they used a method
95
    # where they could have provided a username/password (i.e. CGI), but they 
96
    # did not provide a username/password, then throw an error.
97 4154
    if ($user->authorizer->can_login && !$credentials_provided) {
98 3831
        ThrowUserError('sudo_password_required',
99
                       { target_login => $cgi->param('target_login'),
100
                               reason => $cgi->param('reason')});
101
    }
102
    
103
    # The user must be in the 'bz_sudoers' group
104 3737
    unless ($user->in_group('bz_sudoers')) {
105
        ThrowUserError('auth_failure', {  group => 'bz_sudoers',
106
                                         action => 'begin',
107
                                         object => 'sudo_session' }
108
        );
109
    }
110
    
111 3831
    # Do not try to start a new session if one is already in progress!
112
    if (defined(Bugzilla->sudoer)) {
113
        ThrowUserError('sudo_in_progress', { target => $user->login });
114
    }
115
116
    # Did the user actually go trough the 'sudo-prepare' action?  Do some 
117
    # checks on the token the action should have left.
118
    my ($token_user, $token_timestamp, $token_data) =
119
        Bugzilla::Token::GetTokenData($cgi->param('token'));
120
    unless (defined($token_user)
121
            && defined($token_data)
122
            && ($token_user == $user->id)
123
            && ($token_data eq 'sudo_prepared'))
124
    {
125
        ThrowUserError('sudo_preparation_required', 
126 4113
                       { target_login => scalar $cgi->param('target_login'),
127
                               reason => scalar $cgi->param('reason')});
128 3831
    }
129 4612
    delete_token($cgi->param('token'));
130 3831
131 3737
    # Get & verify the target user (the user who we will be impersonating)
132 3831
    my $target_user = 
133 4444
        new Bugzilla::User({ name => $cgi->param('target_login') });
134 3831
    unless (defined($target_user)
135
            && $target_user->id
136
            && $user->can_see_user($target_user))
137
    {
138
        ThrowUserError('user_match_failed',
139 3737
                       { 'name' => $cgi->param('target_login') }
140
        );
141
    }
142
    if ($target_user->in_group('bz_sudo_protect')) {
143
        ThrowUserError('sudo_protected', { login => $target_user->login });
144
    }
145 3831
146 3795
    # If we have a reason passed in, keep it under 200 characters
147
    my $reason = $cgi->param('reason') || '';
148 7463
    $reason = substr($reason, 0, 200);
149 3795
    
150 3737
    # Calculate the session expiry time (T + 6 hours)
151 7429
    my $time_string = time2str('%a, %d-%b-%Y %T %Z', time + MAX_SUDO_TOKEN_AGE, 'GMT');
152 3737
153
    # For future sessions, store the unique ID of the target user
154 7429
    my $token = Bugzilla::Token::_create_token($user->id, 'sudo', $target_user->id);
155 3831
    $cgi->send_cookie('-name'    => 'sudo',
156
                      '-expires' => $time_string,
157 7429
                      '-value'   => $token
158 3737
    );
159
    
160
    # For the present, change the values of Bugzilla::user & Bugzilla::sudoer
161 3831
    Bugzilla->sudo_request($target_user, $user);
162 3737
    
163
    # NOTE: If you want to log the start of an sudo session, do it here.
164 3795
165
    # Go ahead and send out the message now
166
    my $message;
167 7865
    my $mail_template = Bugzilla->template_inner($target_user->setting('lang'));
168 5542
    $mail_template->process('email/sudo.txt.tmpl', { reason => $reason }, \$message);
169 4190
    MessageToMTA($message);
170 5542
171 3737
    $vars->{'message'} = 'sudo_started';
172
    $vars->{'target'} = $target_user->login;
173
    $target = 'global/message.html.tmpl';
174
}
175
# end-sudo: End the current sudo session (if one is in progress)
176
elsif ($action eq 'end-sudo') {
177
    # Regardless of our state, delete the sudo cookie if it exists
178 7429
    my $token = $cgi->cookie('sudo');
179 3737
    $cgi->remove_cookie('sudo');
180
181
    # Are we in an sudo session?
182
    Bugzilla->login(LOGIN_OPTIONAL);
183
    my $sudoer = Bugzilla->sudoer;
184
    if (defined($sudoer)) {
185
        Bugzilla->sudo_request($sudoer, undef);
186
    }
187 7429
    # Now that the session is over, remove the token from the DB.
188
    delete_token($token);
189 3737
190
    # NOTE: If you want to log the end of an sudo session, so it here.
191
    
192
    $vars->{'message'} = 'sudo_ended';
193
    $target = 'global/message.html.tmpl';
194
}
195 3833
# No valid action found
196
else {
197
    Bugzilla->login(LOGIN_OPTIONAL);
198 7188
    ThrowUserError('unknown_action', {action => $action});
199 3833
}
200 3737
201
# Display the template
202 2352
print $cgi->header();
203 3737
$template->process($target, $vars)
204
      || ThrowTemplateError($template->error());

Loggerhead 1.18.1 is a web-based interface for Bazaar branches