1998-09-16 01:49:26 +04:00
|
|
|
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
|
|
|
#
|
1999-11-02 02:33:56 +03:00
|
|
|
# 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.
|
|
|
|
#
|
1998-09-16 01:49:26 +04:00
|
|
|
# The Original Code is the Bugzilla Bug Tracking System.
|
1999-11-02 02:33:56 +03:00
|
|
|
#
|
1998-09-16 01:49:26 +04:00
|
|
|
# The Initial Developer of the Original Code is Netscape Communications
|
1999-11-02 02:33:56 +03:00
|
|
|
# Corporation. Portions created by Netscape are
|
|
|
|
# Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
# Rights Reserved.
|
|
|
|
#
|
1998-09-16 01:49:26 +04:00
|
|
|
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
1999-12-03 02:21:42 +03:00
|
|
|
# Dan Mosedale <dmose@mozilla.org>
|
2000-09-15 22:35:18 +04:00
|
|
|
# Joe Robins <jmrobins@tgix.com>
|
2001-06-08 00:26:40 +04:00
|
|
|
# Dave Miller <justdave@syndicomm.com>
|
2001-08-26 22:51:45 +04:00
|
|
|
# Christopher Aillon <christopher@aillon.com>
|
1998-09-16 01:49:26 +04:00
|
|
|
|
|
|
|
# Contains some global routines used throughout the CGI scripts of Bugzilla.
|
|
|
|
|
|
|
|
use diagnostics;
|
|
|
|
use strict;
|
2000-03-10 20:45:09 +03:00
|
|
|
# use Carp; # for confess
|
1999-10-19 03:57:58 +04:00
|
|
|
# Shut up misguided -w warnings about "used only once". For some reason,
|
|
|
|
# "use vars" chokes on me when I try it here.
|
2000-10-24 04:44:21 +04:00
|
|
|
|
|
|
|
# commented out the following snippet of code. this tosses errors into the
|
|
|
|
# CGI if you are perl 5.6, and doesn't if you have perl 5.003.
|
2000-09-15 22:35:18 +04:00
|
|
|
# We want to check for the existence of the LDAP modules here.
|
2000-10-24 04:44:21 +04:00
|
|
|
# eval "use Mozilla::LDAP::Conn";
|
|
|
|
# my $have_ldap = $@ ? 0 : 1;
|
|
|
|
|
1999-10-19 03:57:58 +04:00
|
|
|
|
1999-10-19 04:04:59 +04:00
|
|
|
sub CGI_pl_sillyness {
|
1999-10-19 03:57:58 +04:00
|
|
|
my $zz;
|
|
|
|
$zz = %::FILENAME;
|
2000-03-10 20:45:09 +03:00
|
|
|
$zz = %::MFORM;
|
2000-01-21 00:36:20 +03:00
|
|
|
$zz = %::dontchange;
|
1999-10-19 03:57:58 +04:00
|
|
|
}
|
|
|
|
|
1998-09-16 01:49:26 +04:00
|
|
|
use CGI::Carp qw(fatalsToBrowser);
|
|
|
|
|
|
|
|
require 'globals.pl';
|
|
|
|
|
|
|
|
sub GeneratePersonInput {
|
|
|
|
my ($field, $required, $def_value, $extraJavaScript) = (@_);
|
1999-09-23 23:19:02 +04:00
|
|
|
$extraJavaScript ||= "";
|
1998-09-16 01:49:26 +04:00
|
|
|
if ($extraJavaScript ne "") {
|
1999-09-23 23:19:02 +04:00
|
|
|
$extraJavaScript = "onChange=\"$extraJavaScript\"";
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
return "<INPUT NAME=\"$field\" SIZE=32 $extraJavaScript VALUE=\"$def_value\">";
|
|
|
|
}
|
|
|
|
|
|
|
|
sub GeneratePeopleInput {
|
1998-11-20 22:18:37 +03:00
|
|
|
my ($field, $def_value) = (@_);
|
|
|
|
return "<INPUT NAME=\"$field\" SIZE=45 VALUE=\"$def_value\">";
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Implementations of several of the below were blatently stolen from CGI.pm,
|
|
|
|
# by Lincoln D. Stein.
|
|
|
|
|
|
|
|
|
|
|
|
# Get rid of all the %xx encoding and the like from the given URL.
|
|
|
|
|
|
|
|
sub url_decode {
|
|
|
|
my ($todecode) = (@_);
|
|
|
|
$todecode =~ tr/+/ /; # pluses become spaces
|
|
|
|
$todecode =~ s/%([0-9a-fA-F]{2})/pack("c",hex($1))/ge;
|
|
|
|
return $todecode;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Quotify a string, suitable for putting into a URL.
|
|
|
|
|
|
|
|
sub url_quote {
|
|
|
|
my($toencode) = (@_);
|
|
|
|
$toencode=~s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg;
|
|
|
|
return $toencode;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-28 04:01:40 +03:00
|
|
|
sub ParseUrlString {
|
|
|
|
my ($buffer, $f, $m) = (@_);
|
|
|
|
undef %$f;
|
|
|
|
undef %$m;
|
1998-09-16 01:49:26 +04:00
|
|
|
|
|
|
|
my %isnull;
|
|
|
|
my $remaining = $buffer;
|
|
|
|
while ($remaining ne "") {
|
|
|
|
my $item;
|
|
|
|
if ($remaining =~ /^([^&]*)&(.*)$/) {
|
|
|
|
$item = $1;
|
|
|
|
$remaining = $2;
|
|
|
|
} else {
|
|
|
|
$item = $remaining;
|
|
|
|
$remaining = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
my $name;
|
|
|
|
my $value;
|
|
|
|
if ($item =~ /^([^=]*)=(.*)$/) {
|
|
|
|
$name = $1;
|
|
|
|
$value = url_decode($2);
|
|
|
|
} else {
|
|
|
|
$name = $item;
|
|
|
|
$value = "";
|
|
|
|
}
|
|
|
|
if ($value ne "") {
|
2000-01-28 04:01:40 +03:00
|
|
|
if (defined $f->{$name}) {
|
|
|
|
$f->{$name} .= $value;
|
|
|
|
my $ref = $m->{$name};
|
1998-09-16 01:49:26 +04:00
|
|
|
push @$ref, $value;
|
|
|
|
} else {
|
2000-01-28 04:01:40 +03:00
|
|
|
$f->{$name} = $value;
|
|
|
|
$m->{$name} = [$value];
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$isnull{$name} = 1;
|
|
|
|
}
|
|
|
|
}
|
2000-08-21 23:50:41 +04:00
|
|
|
if (%isnull) {
|
1998-09-16 01:49:26 +04:00
|
|
|
foreach my $name (keys(%isnull)) {
|
2000-01-28 04:01:40 +03:00
|
|
|
if (!defined $f->{$name}) {
|
|
|
|
$f->{$name} = "";
|
|
|
|
$m->{$name} = [];
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-28 04:01:40 +03:00
|
|
|
sub ProcessFormFields {
|
|
|
|
my ($buffer) = (@_);
|
|
|
|
return ParseUrlString($buffer, \%::FORM, \%::MFORM);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-04-08 18:40:46 +04:00
|
|
|
sub ProcessMultipartFormFields {
|
|
|
|
my ($boundary) = (@_);
|
|
|
|
$boundary =~ s/^-*//;
|
|
|
|
my $remaining = $ENV{"CONTENT_LENGTH"};
|
|
|
|
my $inheader = 1;
|
|
|
|
my $itemname = "";
|
|
|
|
# open(DEBUG, ">debug") || die "Can't open debugging thing";
|
|
|
|
# print DEBUG "Boundary is '$boundary'\n";
|
|
|
|
while ($remaining > 0 && ($_ = <STDIN>)) {
|
|
|
|
$remaining -= length($_);
|
|
|
|
# print DEBUG "< $_";
|
|
|
|
if ($_ =~ m/^-*$boundary/) {
|
|
|
|
# print DEBUG "Entered header\n";
|
|
|
|
$inheader = 1;
|
|
|
|
$itemname = "";
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($inheader) {
|
|
|
|
if (m/^\s*$/) {
|
|
|
|
$inheader = 0;
|
|
|
|
# print DEBUG "left header\n";
|
|
|
|
$::FORM{$itemname} = "";
|
|
|
|
}
|
|
|
|
if (m/^Content-Disposition:\s*form-data\s*;\s*name\s*=\s*"([^\"]+)"/i) {
|
|
|
|
$itemname = $1;
|
|
|
|
# print DEBUG "Found itemname $itemname\n";
|
|
|
|
if (m/;\s*filename\s*=\s*"([^\"]+)"/i) {
|
|
|
|
$::FILENAME{$itemname} = $1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
$::FORM{$itemname} .= $_;
|
|
|
|
}
|
|
|
|
delete $::FORM{""};
|
|
|
|
# Get rid of trailing newlines.
|
|
|
|
foreach my $i (keys %::FORM) {
|
|
|
|
chomp($::FORM{$i});
|
|
|
|
$::FORM{$i} =~ s/\r$//;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-12-03 02:21:42 +03:00
|
|
|
# check and see if a given field exists, is non-empty, and is set to a
|
|
|
|
# legal value. assume a browser bug and abort appropriately if not.
|
|
|
|
# if $legalsRef is not passed, just check to make sure the value exists and
|
|
|
|
# is non-NULL
|
|
|
|
#
|
|
|
|
sub CheckFormField (\%$;\@) {
|
|
|
|
my ($formRef, # a reference to the form to check (a hash)
|
|
|
|
$fieldname, # the fieldname to check
|
|
|
|
$legalsRef # (optional) ref to a list of legal values
|
|
|
|
) = @_;
|
|
|
|
|
|
|
|
if ( !defined $formRef->{$fieldname} ||
|
|
|
|
trim($formRef->{$fieldname}) eq "" ||
|
|
|
|
(defined($legalsRef) &&
|
|
|
|
lsearch($legalsRef, $formRef->{$fieldname})<0) ){
|
|
|
|
|
|
|
|
print "A legal $fieldname was not set; ";
|
|
|
|
print Param("browserbugmessage");
|
2000-01-15 01:35:49 +03:00
|
|
|
PutFooter();
|
1999-12-03 02:21:42 +03:00
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# check and see if a given field is defined, and abort if not
|
|
|
|
#
|
|
|
|
sub CheckFormFieldDefined (\%$) {
|
|
|
|
my ($formRef, # a reference to the form to check (a hash)
|
|
|
|
$fieldname, # the fieldname to check
|
|
|
|
) = @_;
|
|
|
|
|
|
|
|
if ( !defined $formRef->{$fieldname} ) {
|
|
|
|
print "$fieldname was not defined; ";
|
|
|
|
print Param("browserbugmessage");
|
2000-01-15 01:35:49 +03:00
|
|
|
PutFooter();
|
1999-12-03 02:21:42 +03:00
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
}
|
1999-04-08 18:40:46 +04:00
|
|
|
|
2001-05-31 19:52:25 +04:00
|
|
|
sub ValidateBugID {
|
2001-06-03 02:02:02 +04:00
|
|
|
# Validates and verifies a bug ID, making sure the number is a
|
|
|
|
# positive integer, that it represents an existing bug in the
|
|
|
|
# database, and that the user is authorized to access that bug.
|
|
|
|
|
|
|
|
my ($id) = @_;
|
|
|
|
|
|
|
|
# Make sure the bug number is a positive integer.
|
2001-06-20 02:48:21 +04:00
|
|
|
# Whitespace can be ignored because the SQL server will ignore it.
|
|
|
|
$id =~ /^\s*([1-9][0-9]*)\s*$/
|
2001-06-03 02:02:02 +04:00
|
|
|
|| DisplayError("The bug number is invalid.")
|
|
|
|
&& exit;
|
|
|
|
|
|
|
|
# Get the values of the usergroupset and userid global variables
|
|
|
|
# and write them to local variables for use within this function,
|
|
|
|
# setting those local variables to the default value of zero if
|
|
|
|
# the global variables are undefined.
|
|
|
|
|
|
|
|
# "usergroupset" stores the set of groups the user is a member of,
|
|
|
|
# while "userid" stores the user's unique ID. These variables are
|
|
|
|
# set globally by either confirm_login() or quietly_check_login(),
|
|
|
|
# one of which should be run before calling this function; otherwise
|
|
|
|
# this function will treat the user as if they were not logged in
|
|
|
|
# and throw an error if they try to access a bug that requires
|
|
|
|
# permissions/authorization to access.
|
|
|
|
my $usergroupset = $::usergroupset || 0;
|
|
|
|
my $userid = $::userid || 0;
|
|
|
|
|
|
|
|
# Query the database for the bug, retrieving a boolean value that
|
|
|
|
# represents whether or not the user is authorized to access the bug.
|
|
|
|
|
|
|
|
# Users are authorized to access bugs if they are a member of all
|
|
|
|
# groups to which the bug is restricted. User group membership and
|
|
|
|
# bug restrictions are stored as bits within bitsets, so authorization
|
|
|
|
# can be determined by comparing the intersection of the user's
|
|
|
|
# bitset with the bug's bitset. If the result matches the bug's bitset
|
|
|
|
# the user is a member of all groups to which the bug is restricted
|
|
|
|
# and is authorized to access the bug.
|
|
|
|
|
2001-08-13 04:46:20 +04:00
|
|
|
# A user is also authorized to access a bug if she is the reporter,
|
|
|
|
# assignee, QA contact, or member of the cc: list of the bug and the bug
|
|
|
|
# allows users in those roles to see the bug. The boolean fields
|
|
|
|
# reporter_accessible, assignee_accessible, qacontact_accessible, and
|
|
|
|
# cclist_accessible identify whether or not those roles can see the bug.
|
|
|
|
|
2001-06-03 02:02:02 +04:00
|
|
|
# Bit arithmetic is performed by MySQL instead of Perl because bitset
|
|
|
|
# fields in the database are 64 bits wide (BIGINT), and Perl installations
|
|
|
|
# may or may not support integers larger than 32 bits. Using bitsets
|
|
|
|
# and doing bitset arithmetic is probably not cross-database compatible,
|
|
|
|
# however, so these mechanisms are likely to change in the future.
|
2001-08-13 04:46:20 +04:00
|
|
|
|
|
|
|
# Get data from the database about whether or not the user belongs to
|
|
|
|
# all groups the bug is in, and who are the bug's reporter and qa_contact
|
|
|
|
# along with which roles can always access the bug.
|
|
|
|
SendSQL("SELECT ((groupset & $usergroupset) = groupset) , reporter , assigned_to , qa_contact ,
|
|
|
|
reporter_accessible , assignee_accessible , qacontact_accessible , cclist_accessible
|
|
|
|
FROM bugs
|
|
|
|
WHERE bug_id = $id");
|
2001-06-03 02:02:02 +04:00
|
|
|
|
|
|
|
# Make sure the bug exists in the database.
|
|
|
|
MoreSQLData()
|
|
|
|
|| DisplayError("Bug #$id does not exist.")
|
|
|
|
&& exit;
|
|
|
|
|
2001-08-13 04:46:20 +04:00
|
|
|
my ($isauthorized, $reporter, $assignee, $qacontact, $reporter_accessible,
|
|
|
|
$assignee_accessible, $qacontact_accessible, $cclist_accessible) = FetchSQLData();
|
|
|
|
|
2001-08-21 00:36:10 +04:00
|
|
|
# Finish validation and return if the user is a member of all groups to which the bug belongs.
|
|
|
|
return if $isauthorized;
|
|
|
|
|
|
|
|
# Finish validation and return if the user is in a role that has access to the bug.
|
|
|
|
if ($userid) {
|
|
|
|
return
|
|
|
|
if ($reporter_accessible && $reporter == $userid)
|
|
|
|
|| ($assignee_accessible && $assignee == $userid)
|
|
|
|
|| ($qacontact_accessible && $qacontact == $userid);
|
|
|
|
}
|
2001-08-13 04:46:20 +04:00
|
|
|
|
|
|
|
# Try to authorize the user one more time by seeing if they are on
|
|
|
|
# the cc: list. If so, finish validation and return.
|
|
|
|
if ( $cclist_accessible ) {
|
|
|
|
my @cclist;
|
|
|
|
SendSQL("SELECT cc.who
|
|
|
|
FROM bugs , cc
|
|
|
|
WHERE bugs.bug_id = $id
|
|
|
|
AND cc.bug_id = bugs.bug_id
|
|
|
|
");
|
|
|
|
while (my ($ccwho) = FetchSQLData()) {
|
2001-08-26 22:51:45 +04:00
|
|
|
# more efficient to just check the var here instead of
|
|
|
|
# creating a potentially huge array to grep against
|
|
|
|
return if ($userid == $ccwho);
|
2001-08-13 04:46:20 +04:00
|
|
|
}
|
2001-08-26 22:51:45 +04:00
|
|
|
|
2001-08-13 04:46:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
# The user did not pass any of the authorization tests, which means they
|
|
|
|
# are not authorized to see the bug. Display an error and stop execution.
|
|
|
|
# The error the user sees depends on whether or not they are logged in
|
|
|
|
# (i.e. $userid contains the user's positive integer ID).
|
|
|
|
if ($userid) {
|
|
|
|
DisplayError("You are not authorized to access bug #$id.");
|
|
|
|
} else {
|
|
|
|
DisplayError(
|
|
|
|
qq|You are not authorized to access bug #$id. To see this bug, you
|
|
|
|
must first <a href="show_bug.cgi?id=$id&GoAheadAndLogIn=1">log in
|
|
|
|
to an account</a> with the appropriate permissions.|
|
|
|
|
);
|
|
|
|
}
|
|
|
|
exit;
|
|
|
|
|
2001-05-31 19:52:25 +04:00
|
|
|
}
|
|
|
|
|
1999-12-03 02:21:42 +03:00
|
|
|
# check and see if a given string actually represents a positive
|
|
|
|
# integer, and abort if not.
|
|
|
|
#
|
|
|
|
sub CheckPosInt($) {
|
|
|
|
my ($number) = @_; # the fieldname to check
|
|
|
|
|
|
|
|
if ( $number !~ /^[1-9][0-9]*$/ ) {
|
2001-06-07 05:31:51 +04:00
|
|
|
print "Received string \"$number\" when positive integer expected; ";
|
1999-12-03 02:21:42 +03:00
|
|
|
print Param("browserbugmessage");
|
2000-01-15 01:35:49 +03:00
|
|
|
PutFooter();
|
1999-12-03 02:21:42 +03:00
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
}
|
1999-04-08 18:40:46 +04:00
|
|
|
|
1998-09-16 01:49:26 +04:00
|
|
|
sub FormData {
|
|
|
|
my ($field) = (@_);
|
|
|
|
return $::FORM{$field};
|
|
|
|
}
|
|
|
|
|
|
|
|
sub html_quote {
|
|
|
|
my ($var) = (@_);
|
|
|
|
$var =~ s/\&/\&/g;
|
|
|
|
$var =~ s/</\</g;
|
|
|
|
$var =~ s/>/\>/g;
|
|
|
|
return $var;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub value_quote {
|
|
|
|
my ($var) = (@_);
|
|
|
|
$var =~ s/\&/\&/g;
|
|
|
|
$var =~ s/</\</g;
|
|
|
|
$var =~ s/>/\>/g;
|
|
|
|
$var =~ s/"/\"/g;
|
2000-06-02 03:09:14 +04:00
|
|
|
# See bug http://bugzilla.mozilla.org/show_bug.cgi?id=4928 for
|
|
|
|
# explanaion of why bugzilla does this linebreak substitution.
|
|
|
|
# This caused form submission problems in mozilla (bug 22983, 32000).
|
2001-01-17 00:09:33 +03:00
|
|
|
$var =~ s/\r\n/\
/g;
|
|
|
|
$var =~ s/\n\r/\
/g;
|
1999-04-10 21:42:24 +04:00
|
|
|
$var =~ s/\r/\
/g;
|
2001-01-17 00:09:33 +03:00
|
|
|
$var =~ s/\n/\
/g;
|
1998-09-16 01:49:26 +04:00
|
|
|
return $var;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub navigation_header {
|
1999-05-12 21:18:10 +04:00
|
|
|
if (defined $::COOKIE{"BUGLIST"} && $::COOKIE{"BUGLIST"} ne "" &&
|
|
|
|
defined $::FORM{'id'}) {
|
1998-09-16 01:49:26 +04:00
|
|
|
my @bugs = split(/:/, $::COOKIE{"BUGLIST"});
|
|
|
|
my $cur = lsearch(\@bugs, $::FORM{"id"});
|
|
|
|
print "<B>Bug List:</B> (@{[$cur + 1]} of @{[$#bugs + 1]})\n";
|
|
|
|
print "<A HREF=\"show_bug.cgi?id=$bugs[0]\">First</A>\n";
|
|
|
|
print "<A HREF=\"show_bug.cgi?id=$bugs[$#bugs]\">Last</A>\n";
|
|
|
|
if ($cur > 0) {
|
|
|
|
print "<A HREF=\"show_bug.cgi?id=$bugs[$cur - 1]\">Prev</A>\n";
|
|
|
|
} else {
|
|
|
|
print "<I><FONT COLOR=\#777777>Prev</FONT></I>\n";
|
|
|
|
}
|
|
|
|
if ($cur < $#bugs) {
|
|
|
|
$::next_bug = $bugs[$cur + 1];
|
|
|
|
print "<A HREF=\"show_bug.cgi?id=$::next_bug\">Next</A>\n";
|
|
|
|
} else {
|
|
|
|
print "<I><FONT COLOR=\#777777>Next</FONT></I>\n";
|
|
|
|
}
|
2000-01-22 22:08:57 +03:00
|
|
|
print qq{ <A HREF="buglist.cgi?regetlastlist=1">Show list</A>\n};
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
print " <A HREF=query.cgi>Query page</A>\n";
|
|
|
|
print " <A HREF=enter_bug.cgi>Enter new bug</A>\n"
|
|
|
|
}
|
|
|
|
|
2000-01-15 01:35:49 +03:00
|
|
|
sub make_checkboxes {
|
|
|
|
my ($src,$default,$isregexp,$name) = (@_);
|
|
|
|
my $last = "";
|
|
|
|
my $capitalized = "";
|
|
|
|
my $popup = "";
|
|
|
|
my $found = 0;
|
|
|
|
$default = "" if !defined $default;
|
|
|
|
|
|
|
|
if ($src) {
|
|
|
|
foreach my $item (@$src) {
|
|
|
|
if ($item eq "-blank-" || $item ne $last) {
|
|
|
|
if ($item eq "-blank-") {
|
|
|
|
$item = "";
|
|
|
|
}
|
|
|
|
$last = $item;
|
|
|
|
$capitalized = $item;
|
|
|
|
$capitalized =~ tr/A-Z/a-z/;
|
|
|
|
$capitalized =~ s/^(.?)(.*)/\u$1$2/;
|
|
|
|
if ($isregexp ? $item =~ $default : $default eq $item) {
|
2000-03-07 20:32:51 +03:00
|
|
|
$popup .= "<INPUT NAME=$name TYPE=CHECKBOX VALUE=\"$item\" CHECKED>$capitalized<br>";
|
2000-01-15 01:35:49 +03:00
|
|
|
$found = 1;
|
|
|
|
} else {
|
|
|
|
$popup .= "<INPUT NAME=$name TYPE=CHECKBOX VALUE=\"$item\">$capitalized<br>";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!$found && $default ne "") {
|
2000-03-07 20:32:51 +03:00
|
|
|
$popup .= "<INPUT NAME=$name TYPE=CHECKBOX CHECKED>$default";
|
2000-01-15 01:35:49 +03:00
|
|
|
}
|
|
|
|
return $popup;
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# make_selection_widget: creates an HTML selection widget from a list of text strings.
|
|
|
|
# $groupname is the name of the setting (form value) that this widget will control
|
|
|
|
# $src is the list of options
|
|
|
|
# you can specify a $default value which is either a string or a regex pattern to match to
|
|
|
|
# identify the default value
|
|
|
|
# $capitalize lets you optionally capitalize the option strings; the default is the value
|
|
|
|
# of Param("capitalizelists")
|
|
|
|
# $multiple is 1 if several options are selectable (default), 0 otherwise.
|
|
|
|
# $size is used for lists to control how many items are shown. The default is 7. A list of
|
|
|
|
# size 1 becomes a popup menu.
|
|
|
|
# $preferLists is 1 if selection lists should be used in favor of radio buttons and
|
|
|
|
# checkboxes, and 0 otherwise. The default is the value of Param("preferlists").
|
|
|
|
#
|
|
|
|
# The actual widget generated depends on the parameter settings:
|
|
|
|
#
|
|
|
|
# MULTIPLE PREFERLISTS SIZE RESULT
|
|
|
|
# 0 (single) 0 =1 Popup Menu (normal for list of size 1)
|
|
|
|
# 0 (single) 0 >1 Radio buttons
|
|
|
|
# 0 (single) 1 =1 Popup Menu (normal for list of size 1)
|
|
|
|
# 0 (single) 1 n>1 List of size n, single selection
|
|
|
|
# 1 (multi) 0 n/a Check boxes; size ignored
|
|
|
|
# 1 (multi) 1 n/a List of size n, multiple selection, of size n
|
|
|
|
#
|
|
|
|
sub make_selection_widget {
|
|
|
|
my ($groupname,$src,$default,$isregexp,$multiple, $size, $capitalize, $preferLists) = (@_);
|
|
|
|
my $last = "";
|
|
|
|
my $popup = "";
|
|
|
|
my $found = 0;
|
|
|
|
my $displaytext = "";
|
|
|
|
$groupname = "" if !defined $groupname;
|
|
|
|
$default = "" if !defined $default;
|
|
|
|
$capitalize = Param("capitalizelists") if !defined $capitalize;
|
|
|
|
$multiple = 1 if !defined $multiple;
|
|
|
|
$preferLists = Param("preferlists") if !defined $preferLists;
|
|
|
|
$size = 7 if !defined $size;
|
|
|
|
my $type = "LIST";
|
|
|
|
if (!$preferLists) {
|
|
|
|
if ($multiple) {
|
|
|
|
$type = "CHECKBOX";
|
|
|
|
} else {
|
|
|
|
if ($size > 1) {
|
|
|
|
$type = "RADIO";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($type eq "LIST") {
|
|
|
|
$popup .= "<SELECT NAME=\"$groupname\"";
|
|
|
|
if ($multiple) {
|
|
|
|
$popup .= " MULTIPLE";
|
|
|
|
}
|
|
|
|
$popup .= " SIZE=$size>\n";
|
|
|
|
}
|
|
|
|
if ($src) {
|
|
|
|
foreach my $item (@$src) {
|
|
|
|
if ($item eq "-blank-" || $item ne $last) {
|
|
|
|
if ($item eq "-blank-") {
|
|
|
|
$item = "";
|
|
|
|
}
|
|
|
|
$last = $item;
|
|
|
|
$displaytext = $item;
|
|
|
|
if ($capitalize) {
|
|
|
|
$displaytext =~ tr/A-Z/a-z/;
|
|
|
|
$displaytext =~ s/^(.?)(.*)/\u$1$2/;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($isregexp ? $item =~ $default : $default eq $item) {
|
|
|
|
if ($type eq "CHECKBOX") {
|
|
|
|
$popup .= "<INPUT NAME=$groupname type=checkbox VALUE=\"$item\" CHECKED>$displaytext<br>";
|
|
|
|
} elsif ($type eq "RADIO") {
|
|
|
|
$popup .= "<INPUT NAME=$groupname type=radio VALUE=\"$item\" check>$displaytext<br>";
|
|
|
|
} else {
|
|
|
|
$popup .= "<OPTION SELECTED VALUE=\"$item\">$displaytext";
|
|
|
|
}
|
|
|
|
$found = 1;
|
|
|
|
} else {
|
|
|
|
if ($type eq "CHECKBOX") {
|
|
|
|
$popup .= "<INPUT NAME=$groupname type=checkbox VALUE=\"$item\">$displaytext<br>";
|
|
|
|
} elsif ($type eq "RADIO") {
|
|
|
|
$popup .= "<INPUT NAME=$groupname type=radio VALUE=\"$item\">$displaytext<br>";
|
|
|
|
} else {
|
|
|
|
$popup .= "<OPTION VALUE=\"$item\">$displaytext";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!$found && $default ne "") {
|
|
|
|
if ($type eq "CHECKBOX") {
|
|
|
|
$popup .= "<INPUT NAME=$groupname type=checkbox CHECKED>$default";
|
|
|
|
} elsif ($type eq "RADIO") {
|
|
|
|
$popup .= "<INPUT NAME=$groupname type=radio checked>$default";
|
|
|
|
} else {
|
|
|
|
$popup .= "<OPTION SELECTED>$default";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($type eq "LIST") {
|
|
|
|
$popup .= "</SELECT>";
|
|
|
|
}
|
|
|
|
return $popup;
|
|
|
|
}
|
|
|
|
|
1998-09-16 01:49:26 +04:00
|
|
|
|
1999-12-06 20:09:54 +03:00
|
|
|
$::CheckOptionValues = 1;
|
|
|
|
|
1998-09-16 01:49:26 +04:00
|
|
|
sub make_options {
|
|
|
|
my ($src,$default,$isregexp) = (@_);
|
|
|
|
my $last = "";
|
|
|
|
my $popup = "";
|
|
|
|
my $found = 0;
|
1999-06-11 21:39:19 +04:00
|
|
|
$default = "" if !defined $default;
|
1999-04-27 21:17:49 +04:00
|
|
|
|
|
|
|
if ($src) {
|
|
|
|
foreach my $item (@$src) {
|
|
|
|
if ($item eq "-blank-" || $item ne $last) {
|
|
|
|
if ($item eq "-blank-") {
|
|
|
|
$item = "";
|
|
|
|
}
|
|
|
|
$last = $item;
|
|
|
|
if ($isregexp ? $item =~ $default : $default eq $item) {
|
|
|
|
$popup .= "<OPTION SELECTED VALUE=\"$item\">$item";
|
|
|
|
$found = 1;
|
|
|
|
} else {
|
|
|
|
$popup .= "<OPTION VALUE=\"$item\">$item";
|
|
|
|
}
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!$found && $default ne "") {
|
1999-12-06 20:09:54 +03:00
|
|
|
if ( Param("strictvaluechecks") && $::CheckOptionValues &&
|
1999-12-03 02:56:07 +03:00
|
|
|
($default ne $::dontchange) && ($default ne "-All-") &&
|
|
|
|
($default ne "DUPLICATE") ) {
|
1999-12-03 02:21:42 +03:00
|
|
|
print "Possible bug database corruption has been detected. " .
|
|
|
|
"Please send mail to " . Param("maintainer") . " with " .
|
|
|
|
"details of what you were doing when this message " .
|
|
|
|
"appeared. Thank you.\n";
|
2000-03-23 21:20:34 +03:00
|
|
|
if (!$src) {
|
|
|
|
$src = ["???null???"];
|
|
|
|
}
|
|
|
|
print "<pre>src = " . value_quote(join(' ', @$src)) . "\n";
|
|
|
|
print "default = " . value_quote($default) . "</pre>";
|
2000-04-28 03:12:44 +04:00
|
|
|
PutFooter();
|
2000-03-10 20:45:09 +03:00
|
|
|
# confess "Gulp.";
|
1999-12-03 02:21:42 +03:00
|
|
|
exit 0;
|
|
|
|
|
|
|
|
} else {
|
1998-11-20 22:18:37 +03:00
|
|
|
$popup .= "<OPTION SELECTED>$default";
|
1999-12-03 02:21:42 +03:00
|
|
|
}
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
return $popup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sub make_popup {
|
|
|
|
my ($name,$src,$default,$listtype,$onchange) = (@_);
|
1998-11-20 22:18:37 +03:00
|
|
|
my $popup = "<SELECT NAME=$name";
|
1998-09-16 01:49:26 +04:00
|
|
|
if ($listtype > 0) {
|
1998-11-20 22:18:37 +03:00
|
|
|
$popup .= " SIZE=5";
|
1998-09-16 01:49:26 +04:00
|
|
|
if ($listtype == 2) {
|
|
|
|
$popup .= " MULTIPLE";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (defined $onchange && $onchange ne "") {
|
|
|
|
$popup .= " onchange=$onchange";
|
|
|
|
}
|
|
|
|
$popup .= ">" . make_options($src, $default,
|
|
|
|
($listtype == 2 && $default ne ""));
|
|
|
|
$popup .= "</SELECT>";
|
|
|
|
return $popup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-25 10:54:57 +03:00
|
|
|
sub BuildPulldown {
|
|
|
|
my ($name, $valuelist, $default) = (@_);
|
|
|
|
|
|
|
|
my $entry = qq{<SELECT NAME="$name">};
|
|
|
|
foreach my $i (@$valuelist) {
|
|
|
|
my ($tag, $desc) = (@$i);
|
|
|
|
my $selectpart = "";
|
|
|
|
if ($tag eq $default) {
|
|
|
|
$selectpart = " SELECTED";
|
|
|
|
}
|
2000-02-17 08:15:23 +03:00
|
|
|
if (!defined $desc) {
|
|
|
|
$desc = $tag;
|
|
|
|
}
|
2000-01-25 10:54:57 +03:00
|
|
|
$entry .= qq{<OPTION$selectpart VALUE="$tag">$desc\n};
|
|
|
|
}
|
|
|
|
$entry .= qq{</SELECT>};
|
|
|
|
return $entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-09-16 01:49:26 +04:00
|
|
|
sub PasswordForLogin {
|
|
|
|
my ($login) = (@_);
|
|
|
|
SendSQL("select cryptpassword from profiles where login_name = " .
|
|
|
|
SqlQuote($login));
|
1998-10-13 22:15:37 +04:00
|
|
|
my $result = FetchOneColumn();
|
|
|
|
if (!defined $result) {
|
|
|
|
$result = "";
|
|
|
|
}
|
|
|
|
return $result;
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
|
1999-03-11 19:30:54 +03:00
|
|
|
|
|
|
|
sub quietly_check_login() {
|
|
|
|
$::usergroupset = '0';
|
|
|
|
my $loginok = 0;
|
2000-01-19 01:41:26 +03:00
|
|
|
$::disabledreason = '';
|
2000-02-17 08:15:23 +03:00
|
|
|
$::userid = 0;
|
1999-03-11 19:30:54 +03:00
|
|
|
if (defined $::COOKIE{"Bugzilla_login"} &&
|
|
|
|
defined $::COOKIE{"Bugzilla_logincookie"}) {
|
|
|
|
ConnectToDatabase();
|
1999-06-11 21:39:19 +04:00
|
|
|
if (!defined $ENV{'REMOTE_HOST'}) {
|
|
|
|
$ENV{'REMOTE_HOST'} = $ENV{'REMOTE_ADDR'};
|
|
|
|
}
|
2000-02-17 08:15:23 +03:00
|
|
|
SendSQL("SELECT profiles.userid, profiles.groupset, " .
|
|
|
|
"profiles.login_name, " .
|
1999-05-24 23:42:28 +04:00
|
|
|
"profiles.login_name = " .
|
1999-03-11 19:30:54 +03:00
|
|
|
SqlQuote($::COOKIE{"Bugzilla_login"}) .
|
2000-02-17 08:15:23 +03:00
|
|
|
" AND profiles.cryptpassword = logincookies.cryptpassword " .
|
|
|
|
"AND logincookies.hostname = " .
|
1999-03-11 19:30:54 +03:00
|
|
|
SqlQuote($ENV{"REMOTE_HOST"}) .
|
2000-01-19 01:41:26 +03:00
|
|
|
", profiles.disabledtext " .
|
2000-02-17 08:15:23 +03:00
|
|
|
" FROM profiles, logincookies WHERE logincookies.cookie = " .
|
1999-03-23 02:48:39 +03:00
|
|
|
SqlQuote($::COOKIE{"Bugzilla_logincookie"}) .
|
2000-02-17 08:15:23 +03:00
|
|
|
" AND profiles.userid = logincookies.userid");
|
1999-03-11 19:30:54 +03:00
|
|
|
my @row;
|
|
|
|
if (@row = FetchSQLData()) {
|
2000-02-17 08:15:23 +03:00
|
|
|
my ($userid, $groupset, $loginname, $ok, $disabledtext) = (@row);
|
2000-01-19 01:41:26 +03:00
|
|
|
if ($ok) {
|
|
|
|
if ($disabledtext eq '') {
|
|
|
|
$loginok = 1;
|
2000-02-17 08:15:23 +03:00
|
|
|
$::userid = $userid;
|
2000-01-19 01:41:26 +03:00
|
|
|
$::usergroupset = $groupset;
|
|
|
|
$::COOKIE{"Bugzilla_login"} = $loginname; # Makes sure case
|
|
|
|
# is in
|
|
|
|
# canonical form.
|
|
|
|
} else {
|
|
|
|
$::disabledreason = $disabledtext;
|
|
|
|
}
|
1999-03-11 19:30:54 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-05-08 22:12:28 +04:00
|
|
|
# if 'who' is passed in, verify that it's a good value
|
|
|
|
if ($::FORM{'who'}) {
|
|
|
|
my $whoid = DBname_to_id($::FORM{'who'});
|
|
|
|
delete $::FORM{'who'} unless $whoid;
|
|
|
|
}
|
1999-04-27 21:17:49 +04:00
|
|
|
if (!$loginok) {
|
|
|
|
delete $::COOKIE{"Bugzilla_login"};
|
|
|
|
}
|
1999-03-11 19:30:54 +03:00
|
|
|
return $loginok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-03-27 05:28:51 +03:00
|
|
|
sub CheckEmailSyntax {
|
|
|
|
my ($addr) = (@_);
|
1999-06-14 21:33:52 +04:00
|
|
|
my $match = Param('emailregexp');
|
2001-07-04 11:06:00 +04:00
|
|
|
if ($addr !~ /$match/ || $addr =~ /[\\\(\)<>&,;:"\[\] \t\r\n]/) {
|
1999-03-27 05:28:51 +03:00
|
|
|
print "Content-type: text/html\n\n";
|
|
|
|
|
2001-05-11 22:02:38 +04:00
|
|
|
# For security, escape HTML special characters.
|
|
|
|
$addr = html_quote($addr);
|
|
|
|
|
1999-09-23 23:08:03 +04:00
|
|
|
PutHeader("Check e-mail syntax");
|
1999-03-27 05:28:51 +03:00
|
|
|
print "The e-mail address you entered\n";
|
|
|
|
print "(<b>$addr</b>) didn't match our minimal\n";
|
1999-06-14 21:33:52 +04:00
|
|
|
print "syntax checking for a legal email address.\n";
|
2001-07-04 11:06:00 +04:00
|
|
|
print Param('emailregexpdesc') . "\n";
|
|
|
|
print "It must also not contain any of these special characters: " .
|
|
|
|
"<tt>\\ ( ) & < > , ; : \" [ ]</tt> " .
|
|
|
|
"or any whitespace.\n";
|
|
|
|
print "<p>Please click <b>Back</b> and try again.\n";
|
2000-01-15 01:35:49 +03:00
|
|
|
PutFooter();
|
1999-03-27 05:28:51 +03:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-05-08 02:07:21 +04:00
|
|
|
sub MailPassword {
|
|
|
|
my ($login, $password) = (@_);
|
|
|
|
my $urlbase = Param("urlbase");
|
2000-02-08 01:11:55 +03:00
|
|
|
my $template = Param("passwordmail");
|
|
|
|
my $msg = PerformSubsts($template,
|
|
|
|
{"mailaddress" => $login . Param('emailsuffix'),
|
|
|
|
"login" => $login,
|
|
|
|
"password" => $password});
|
1999-05-08 02:07:21 +04:00
|
|
|
|
|
|
|
open SENDMAIL, "|/usr/lib/sendmail -t";
|
|
|
|
print SENDMAIL $msg;
|
|
|
|
close SENDMAIL;
|
|
|
|
|
|
|
|
print "The password for the e-mail address\n";
|
|
|
|
print "$login has been e-mailed to that address.\n";
|
|
|
|
print "<p>When the e-mail arrives, you can click <b>Back</b>\n";
|
|
|
|
print "and enter your password in the form there.\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-09-16 01:49:26 +04:00
|
|
|
sub confirm_login {
|
|
|
|
my ($nexturl) = (@_);
|
|
|
|
|
|
|
|
# Uncommenting the next line can help debugging...
|
|
|
|
# print "Content-type: text/plain\n\n";
|
|
|
|
|
|
|
|
ConnectToDatabase();
|
2000-09-15 22:35:18 +04:00
|
|
|
# I'm going to reorganize some of this stuff a bit. Since we're adding
|
|
|
|
# a second possible validation method (LDAP), we need to move some of this
|
|
|
|
# to a later section. -Joe Robins, 8/3/00
|
|
|
|
my $enteredlogin = "";
|
|
|
|
my $realcryptpwd = "";
|
|
|
|
|
2001-07-11 09:29:21 +04:00
|
|
|
# If the form contains Bugzilla login and password fields, use Bugzilla's
|
|
|
|
# built-in authentication to authenticate the user (otherwise use LDAP below).
|
|
|
|
if (defined $::FORM{"Bugzilla_login"} && defined $::FORM{"Bugzilla_password"}) {
|
|
|
|
# Make sure the user's login name is a valid email address.
|
|
|
|
$enteredlogin = $::FORM{"Bugzilla_login"};
|
|
|
|
CheckEmailSyntax($enteredlogin);
|
|
|
|
|
|
|
|
# Retrieve the user's ID and crypted password from the database.
|
|
|
|
my $userid;
|
|
|
|
SendSQL("SELECT userid, cryptpassword FROM profiles
|
|
|
|
WHERE login_name = " . SqlQuote($enteredlogin));
|
|
|
|
($userid, $realcryptpwd) = FetchSQLData();
|
|
|
|
|
2001-07-16 23:38:34 +04:00
|
|
|
# Make sure the user exists or throw an error (but do not admit it was a username
|
|
|
|
# error to make it harder for a cracker to find account names by brute force).
|
|
|
|
$userid
|
|
|
|
|| DisplayError("The username or password you entered is not valid.")
|
|
|
|
&& exit;
|
|
|
|
|
2001-07-11 09:29:21 +04:00
|
|
|
# If this is a new user, generate a password, insert a record
|
|
|
|
# into the database, and email their password to them.
|
|
|
|
if ( defined $::FORM{"PleaseMailAPassword"} && !$userid ) {
|
|
|
|
my $password = InsertNewUser($enteredlogin, "");
|
|
|
|
print "Content-Type: text/html\n\n";
|
|
|
|
PutHeader("Account Created");
|
|
|
|
MailPassword($enteredlogin, $password);
|
|
|
|
PutFooter();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Otherwise, authenticate the user.
|
|
|
|
else {
|
|
|
|
# Get the salt from the user's crypted password.
|
|
|
|
my $salt = $realcryptpwd;
|
|
|
|
|
|
|
|
# Using the salt, crypt the password the user entered.
|
|
|
|
my $enteredCryptedPassword = crypt( $::FORM{"Bugzilla_password"} , $salt );
|
|
|
|
|
|
|
|
# Make sure the passwords match or throw an error.
|
|
|
|
($enteredCryptedPassword eq $realcryptpwd)
|
|
|
|
|| DisplayError("The username or password you entered is not valid.")
|
|
|
|
&& exit;
|
|
|
|
|
|
|
|
# If the user has successfully logged in, delete any password tokens
|
|
|
|
# lying around in the system for them.
|
|
|
|
use Token;
|
|
|
|
my $token = Token::HasPasswordToken($userid);
|
|
|
|
while ( $token ) {
|
|
|
|
Token::Cancel($token, "user logged in");
|
|
|
|
$token = Token::HasPasswordToken($userid);
|
|
|
|
}
|
|
|
|
}
|
2000-09-15 22:35:18 +04:00
|
|
|
|
|
|
|
} elsif (Param("useLDAP") &&
|
|
|
|
defined $::FORM{"LDAP_login"} &&
|
|
|
|
defined $::FORM{"LDAP_password"}) {
|
|
|
|
# If we're using LDAP for login, we've got an entirely different
|
|
|
|
# set of things to check.
|
2000-10-24 04:44:21 +04:00
|
|
|
|
|
|
|
# see comment at top of file near eval
|
2000-09-15 22:35:18 +04:00
|
|
|
# First, if we don't have the LDAP modules available to us, we can't
|
|
|
|
# do this.
|
2000-10-24 04:44:21 +04:00
|
|
|
# if(!$have_ldap) {
|
|
|
|
# print "Content-type: text/html\n\n";
|
|
|
|
# PutHeader("LDAP not enabled");
|
|
|
|
# print "The necessary modules for LDAP login are not installed on ";
|
|
|
|
# print "this machine. Please send mail to ".Param("maintainer");
|
|
|
|
# print " and notify him of this problem.\n";
|
|
|
|
# PutFooter();
|
|
|
|
# exit;
|
|
|
|
# }
|
2000-09-15 22:35:18 +04:00
|
|
|
|
|
|
|
# Next, we need to bind anonymously to the LDAP server. This is
|
|
|
|
# because we need to get the Distinguished Name of the user trying
|
|
|
|
# to log in. Some servers (such as iPlanet) allow you to have unique
|
|
|
|
# uids spread out over a subtree of an area (such as "People"), so
|
|
|
|
# just appending the Base DN to the uid isn't sufficient to get the
|
|
|
|
# user's DN. For servers which don't work this way, there will still
|
|
|
|
# be no harm done.
|
|
|
|
my $LDAPserver = Param("LDAPserver");
|
|
|
|
if ($LDAPserver eq "") {
|
|
|
|
print "Content-type: text/html\n\n";
|
|
|
|
PutHeader("LDAP server not defined");
|
|
|
|
print "The LDAP server for authentication has not been defined. ";
|
|
|
|
print "Please contact ".Param("maintainer")." ";
|
|
|
|
print "and notify him of this problem.\n";
|
|
|
|
PutFooter();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
my $LDAPport = "389"; #default LDAP port
|
|
|
|
if($LDAPserver =~ /:/) {
|
|
|
|
($LDAPserver, $LDAPport) = split(":",$LDAPserver);
|
|
|
|
}
|
|
|
|
my $LDAPconn = new Mozilla::LDAP::Conn($LDAPserver,$LDAPport);
|
|
|
|
if(!$LDAPconn) {
|
|
|
|
print "Content-type: text/html\n\n";
|
|
|
|
PutHeader("Unable to connect to LDAP server");
|
|
|
|
print "I was unable to connect to the LDAP server for user ";
|
|
|
|
print "authentication. Please contact ".Param("maintainer");
|
|
|
|
print " and notify him of this problem.\n";
|
|
|
|
PutFooter();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
# We've got our anonymous bind; let's look up this user.
|
|
|
|
my $dnEntry = $LDAPconn->search(Param("LDAPBaseDN"),"subtree","uid=".$::FORM{"LDAP_login"});
|
|
|
|
if(!$dnEntry) {
|
|
|
|
print "Content-type: text/html\n\n";
|
|
|
|
PutHeader("Login Failed");
|
|
|
|
print "The username or password you entered is not valid.\n";
|
|
|
|
print "Please click <b>Back</b> and try again.\n";
|
|
|
|
PutFooter();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Now we get the DN from this search. Once we've got that, we're
|
|
|
|
# done with the anonymous bind, so we close it.
|
|
|
|
my $userDN = $dnEntry->getDN;
|
|
|
|
$LDAPconn->close;
|
|
|
|
|
|
|
|
# Now we attempt to bind as the specified user.
|
|
|
|
$LDAPconn = new Mozilla::LDAP::Conn($LDAPserver,$LDAPport,$userDN,$::FORM{"LDAP_password"});
|
|
|
|
if(!$LDAPconn) {
|
|
|
|
print "Content-type: text/html\n\n";
|
|
|
|
PutHeader("Login Failed");
|
|
|
|
print "The username or password you entered is not valid.\n";
|
|
|
|
print "Please click <b>Back</b> and try again.\n";
|
|
|
|
PutFooter();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
# And now we're going to repeat the search, so that we can get the
|
|
|
|
# mail attribute for this user.
|
|
|
|
my $userEntry = $LDAPconn->search(Param("LDAPBaseDN"),"subtree","uid=".$::FORM{"LDAP_login"});
|
|
|
|
if(!$userEntry->exists(Param("LDAPmailattribute"))) {
|
|
|
|
print "Content-type: text/html\n\n";
|
|
|
|
PutHeader("LDAP authentication error");
|
|
|
|
print "I was unable to retrieve the ".Param("LDAPmailattribute");
|
|
|
|
print " attribute from the LDAP server. Please contact ";
|
|
|
|
print Param("maintainer")." and notify him of this error.\n";
|
|
|
|
PutFooter();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Mozilla::LDAP::Entry->getValues returns an array for the attribute
|
|
|
|
# requested, even if there's only one entry.
|
|
|
|
$enteredlogin = ($userEntry->getValues(Param("LDAPmailattribute")))[0];
|
|
|
|
|
|
|
|
# We're going to need the cryptpwd for this user from the database
|
|
|
|
# so that we can set the cookie below, even though we're not going
|
|
|
|
# to use it for authentication.
|
|
|
|
$realcryptpwd = PasswordForLogin($enteredlogin);
|
|
|
|
|
|
|
|
# If we don't get a result, then we've got a user who isn't in
|
|
|
|
# Bugzilla's database yet, so we've got to add them.
|
|
|
|
if($realcryptpwd eq "") {
|
|
|
|
# We'll want the user's name for this.
|
|
|
|
my $userRealName = ($userEntry->getValues("displayName"))[0];
|
|
|
|
if($userRealName eq "") {
|
|
|
|
$userRealName = ($userEntry->getValues("cn"))[0];
|
|
|
|
}
|
|
|
|
InsertNewUser($enteredlogin, $userRealName);
|
|
|
|
$realcryptpwd = PasswordForLogin($enteredlogin);
|
|
|
|
}
|
|
|
|
} # end LDAP authentication
|
|
|
|
|
|
|
|
# And now, if we've logged in via either method, then we need to set
|
|
|
|
# the cookies.
|
|
|
|
if($enteredlogin ne "") {
|
|
|
|
$::COOKIE{"Bugzilla_login"} = $enteredlogin;
|
|
|
|
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("select LAST_INSERT_ID()");
|
|
|
|
my $logincookie = FetchOneColumn();
|
|
|
|
|
|
|
|
$::COOKIE{"Bugzilla_logincookie"} = $logincookie;
|
|
|
|
print "Set-Cookie: Bugzilla_login=$enteredlogin ; path=/; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
|
|
|
|
print "Set-Cookie: Bugzilla_logincookie=$logincookie ; path=/; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
|
|
|
|
|
|
|
|
# This next one just cleans out any old bugzilla passwords that may
|
|
|
|
# be sitting around in the cookie files, from the bad old days when
|
|
|
|
# we actually stored the password there.
|
|
|
|
print "Set-Cookie: Bugzilla_password= ; path=/; expires=Sun, 30-Jun-80 00:00:00 GMT\n";
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-03-11 19:30:54 +03:00
|
|
|
my $loginok = quietly_check_login();
|
1998-09-16 01:49:26 +04:00
|
|
|
|
1999-03-11 19:30:54 +03:00
|
|
|
if ($loginok != 1) {
|
2000-01-19 01:41:26 +03:00
|
|
|
if ($::disabledreason) {
|
|
|
|
print "Set-Cookie: Bugzilla_login= ; path=/; expires=Sun, 30-Jun-80 00:00:00 GMT
|
|
|
|
Set-Cookie: Bugzilla_logincookie= ; path=/; expires=Sun, 30-Jun-80 00:00:00 GMT
|
|
|
|
Set-Cookie: Bugzilla_password= ; path=/; expires=Sun, 30-Jun-80 00:00:00 GMT
|
|
|
|
Content-type: text/html
|
|
|
|
|
|
|
|
";
|
|
|
|
PutHeader("Your account has been disabled");
|
|
|
|
print $::disabledreason;
|
|
|
|
print "<HR>\n";
|
|
|
|
print "If you believe your account should be restored, please\n";
|
|
|
|
print "send email to " . Param("maintainer") . " explaining\n";
|
|
|
|
print "why.\n";
|
|
|
|
PutFooter();
|
|
|
|
exit();
|
|
|
|
}
|
1998-09-16 01:49:26 +04:00
|
|
|
print "Content-type: text/html\n\n";
|
2001-08-13 23:11:35 +04:00
|
|
|
PutHeader("Login");
|
2000-09-15 22:35:18 +04:00
|
|
|
if(Param("useLDAP")) {
|
|
|
|
print "I need a legitimate LDAP username and password to continue.\n";
|
|
|
|
} else {
|
|
|
|
print "I need a legitimate e-mail address and password to continue.\n";
|
|
|
|
}
|
1998-09-16 01:49:26 +04:00
|
|
|
if (!defined $nexturl || $nexturl eq "") {
|
|
|
|
# Sets nexturl to be argv0, stripping everything up to and
|
2001-06-19 03:13:18 +04:00
|
|
|
# including the last slash (or backslash on Windows).
|
|
|
|
$0 =~ m:[^/\\]*$:;
|
1998-09-16 01:49:26 +04:00
|
|
|
$nexturl = $&;
|
|
|
|
}
|
|
|
|
my $method = "POST";
|
2001-06-08 00:26:40 +04:00
|
|
|
# We always want to use POST here, because we're submitting a password and don't
|
|
|
|
# want to see it in the location bar in the browser in case a co-worker is looking
|
|
|
|
# over your shoulder. If you have cookies off and need to bookmark the query, you
|
|
|
|
# can bookmark it from the screen asking for your password, and it should still
|
|
|
|
# work. See http://bugzilla.mozilla.org/show_bug.cgi?id=15980
|
|
|
|
# if (defined $ENV{"REQUEST_METHOD"} && length($::buffer) > 1) {
|
|
|
|
# $method = $ENV{"REQUEST_METHOD"};
|
|
|
|
# }
|
1998-09-16 01:49:26 +04:00
|
|
|
print "
|
|
|
|
<FORM action=$nexturl method=$method>
|
|
|
|
<table>
|
2000-09-15 22:35:18 +04:00
|
|
|
<tr>";
|
|
|
|
if(Param("useLDAP")) {
|
|
|
|
print "
|
|
|
|
<td align=right><b>Username:</b></td>
|
|
|
|
<td><input size=10 name=LDAP_login></td>
|
|
|
|
</tr>
|
1998-09-16 01:49:26 +04:00
|
|
|
<tr>
|
2000-09-15 22:35:18 +04:00
|
|
|
<td align=right><b>Password:</b></td>
|
|
|
|
<td><input type=password size=10 name=LDAP_password></td>";
|
|
|
|
} else {
|
|
|
|
print "
|
1998-09-16 01:49:26 +04:00
|
|
|
<td align=right><b>E-mail address:</b></td>
|
|
|
|
<td><input size=35 name=Bugzilla_login></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align=right><b>Password:</b></td>
|
2000-09-15 22:35:18 +04:00
|
|
|
<td><input type=password size=35 name=Bugzilla_password></td>";
|
|
|
|
}
|
|
|
|
print "
|
1998-09-16 01:49:26 +04:00
|
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
";
|
2001-07-11 09:29:21 +04:00
|
|
|
# Add all the form fields into the form as hidden fields
|
|
|
|
# (except for Bugzilla_login and Bugzilla_password which we
|
|
|
|
# already added as text fields above).
|
|
|
|
foreach my $i ( grep( $_ !~ /^Bugzilla_/ , keys %::FORM ) ) {
|
|
|
|
print qq|<input type="hidden" name="$i" value="@{[value_quote($::FORM{$i})]}">\n|;
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
2001-07-11 09:29:21 +04:00
|
|
|
|
|
|
|
print qq|
|
|
|
|
<input type="submit" name="GoAheadAndLogIn" value="Login">
|
|
|
|
</form>
|
|
|
|
|;
|
|
|
|
|
|
|
|
# Allow the user to request a token to change their password (unless
|
|
|
|
# we are using LDAP, in which case the user must use LDAP to change it).
|
|
|
|
unless( Param("useLDAP") ) {
|
|
|
|
print qq|
|
|
|
|
<hr>
|
|
|
|
<form method="get" action="token.cgi">
|
|
|
|
<input type="hidden" name="a" value="reqpw">
|
2001-08-16 10:43:21 +04:00
|
|
|
If you have forgotten your password,
|
2001-07-11 09:29:21 +04:00
|
|
|
enter your login name below and submit a request
|
|
|
|
to change your password.<br>
|
|
|
|
<input size="35" name="loginname">
|
|
|
|
<input type="submit" value="Submit Request">
|
|
|
|
</form>
|
2001-08-16 10:43:21 +04:00
|
|
|
<hr>
|
|
|
|
If you don't have a Bugzilla account, you can <a href="createaccount.cgi">create a new account</a>.
|
2001-07-11 09:29:21 +04:00
|
|
|
|;
|
2000-09-15 22:35:18 +04:00
|
|
|
}
|
1998-09-16 01:49:26 +04:00
|
|
|
|
|
|
|
# This seems like as good as time as any to get rid of old
|
|
|
|
# crufty junk in the logincookies table. Get rid of any entry
|
|
|
|
# that hasn't been used in a month.
|
2000-02-18 00:41:39 +03:00
|
|
|
if ($::dbwritesallowed) {
|
|
|
|
SendSQL("DELETE FROM logincookies " .
|
|
|
|
"WHERE TO_DAYS(NOW()) - TO_DAYS(lastused) > 30");
|
|
|
|
}
|
1998-09-16 01:49:26 +04:00
|
|
|
|
|
|
|
|
2000-01-15 01:35:49 +03:00
|
|
|
PutFooter();
|
1998-09-16 01:49:26 +04:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Update the timestamp on our logincookie, so it'll keep on working.
|
2000-02-18 00:41:39 +03:00
|
|
|
if ($::dbwritesallowed) {
|
|
|
|
SendSQL("UPDATE logincookies SET lastused = null " .
|
|
|
|
"WHERE cookie = $::COOKIE{'Bugzilla_logincookie'}");
|
|
|
|
}
|
2000-02-17 08:15:23 +03:00
|
|
|
return $::userid;
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sub PutHeader {
|
2001-08-13 23:11:35 +04:00
|
|
|
my ($title, $h1, $h2, $extra, $jscript) = (@_);
|
1998-09-16 01:49:26 +04:00
|
|
|
|
|
|
|
if (!defined $h1) {
|
|
|
|
$h1 = $title;
|
|
|
|
}
|
|
|
|
if (!defined $h2) {
|
|
|
|
$h2 = "";
|
|
|
|
}
|
1999-08-24 19:24:50 +04:00
|
|
|
if (!defined $extra) {
|
|
|
|
$extra = "";
|
|
|
|
}
|
2000-02-15 21:56:31 +03:00
|
|
|
$jscript ||= "";
|
2001-08-13 23:11:35 +04:00
|
|
|
# If we are shutdown, we want a very basic page to give that
|
|
|
|
# information. Also, the page title should indicate that
|
|
|
|
# we are down.
|
|
|
|
if (Param('shutdownhtml')) {
|
|
|
|
$title = "Bugzilla is Down";
|
|
|
|
$h1 = "Bugzilla is currently down";
|
|
|
|
$h2 = "";
|
|
|
|
$extra = "";
|
|
|
|
$jscript = "";
|
|
|
|
}
|
1998-09-16 01:49:26 +04:00
|
|
|
|
1999-04-27 21:17:49 +04:00
|
|
|
print "<HTML><HEAD>\n<TITLE>$title</TITLE>\n";
|
2000-02-15 21:56:31 +03:00
|
|
|
print Param("headerhtml") . "\n$jscript\n</HEAD>\n";
|
2000-09-16 18:08:37 +04:00
|
|
|
print "<BODY " . Param("bodyhtml") . " $extra>\n";
|
1998-09-16 01:49:26 +04:00
|
|
|
|
1998-09-19 08:38:12 +04:00
|
|
|
print PerformSubsts(Param("bannerhtml"), undef);
|
1998-09-16 01:49:26 +04:00
|
|
|
|
2000-01-15 01:35:49 +03:00
|
|
|
print "<TABLE BORDER=0 CELLSPACING=0 WIDTH=\"100%\">\n";
|
1998-09-16 01:49:26 +04:00
|
|
|
print " <TR>\n";
|
2000-01-15 01:35:49 +03:00
|
|
|
print " <TD WIDTH=10% VALIGN=TOP ALIGN=LEFT>\n";
|
1998-09-16 01:49:26 +04:00
|
|
|
print " <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=2>\n";
|
2000-01-15 01:35:49 +03:00
|
|
|
print " <TR><TD VALIGN=TOP ALIGN=LEFT NOWRAP>\n";
|
|
|
|
print " <FONT SIZE=+1><B>$h1</B></FONT>";
|
1998-09-16 01:49:26 +04:00
|
|
|
print " </TD></TR>\n";
|
|
|
|
print " </TABLE>\n";
|
|
|
|
print " </TD>\n";
|
2000-01-15 01:35:49 +03:00
|
|
|
print " <TD VALIGN=CENTER> </TD>\n";
|
|
|
|
print " <TD VALIGN=CENTER ALIGN=LEFT>\n";
|
1998-09-16 01:49:26 +04:00
|
|
|
|
2000-01-15 01:35:49 +03:00
|
|
|
print "$h2\n";
|
|
|
|
print "</TD></TR></TABLE>\n";
|
1998-09-16 01:49:26 +04:00
|
|
|
|
2000-01-12 21:55:24 +03:00
|
|
|
if (Param("shutdownhtml")) {
|
2001-08-13 23:11:35 +04:00
|
|
|
# If we are dealing with the params page, we want
|
|
|
|
# to ignore shutdownhtml
|
|
|
|
if ($0 !~ m:[\\/](do)?editparams.cgi$:) {
|
|
|
|
print "<p>\n";
|
2000-01-12 21:55:24 +03:00
|
|
|
print Param("shutdownhtml");
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
}
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-15 01:35:49 +03:00
|
|
|
sub PutFooter {
|
2000-02-19 00:38:23 +03:00
|
|
|
print PerformSubsts(Param("footerhtml"));
|
|
|
|
SyncAnyPendingShadowChanges();
|
2000-01-15 01:35:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-05-10 06:53:22 +04:00
|
|
|
sub DisplayError {
|
|
|
|
my ($message, $title) = (@_);
|
|
|
|
$title ||= "Error";
|
|
|
|
|
|
|
|
print "Content-type: text/html\n\n";
|
|
|
|
PutHeader($title);
|
|
|
|
|
|
|
|
print PerformSubsts( Param("errorhtml") , {errormsg => $message} );
|
|
|
|
|
|
|
|
PutFooter();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2000-02-25 22:32:47 +03:00
|
|
|
sub PuntTryAgain ($) {
|
|
|
|
my ($str) = (@_);
|
|
|
|
print PerformSubsts(Param("errorhtml"),
|
|
|
|
{errormsg => $str});
|
2001-02-24 00:40:03 +03:00
|
|
|
SendSQL("UNLOCK TABLES");
|
2000-02-25 22:32:47 +03:00
|
|
|
PutFooter();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-02-17 08:15:23 +03:00
|
|
|
sub CheckIfVotedConfirmed {
|
|
|
|
my ($id, $who) = (@_);
|
|
|
|
SendSQL("SELECT bugs.votes, bugs.bug_status, products.votestoconfirm, " .
|
|
|
|
" bugs.everconfirmed " .
|
|
|
|
"FROM bugs, products " .
|
|
|
|
"WHERE bugs.bug_id = $id AND products.product = bugs.product");
|
|
|
|
my ($votes, $status, $votestoconfirm, $everconfirmed) = (FetchSQLData());
|
|
|
|
if ($votes >= $votestoconfirm && $status eq $::unconfirmedstate) {
|
|
|
|
SendSQL("UPDATE bugs SET bug_status = 'NEW', everconfirmed = 1 " .
|
|
|
|
"WHERE bug_id = $id");
|
|
|
|
my $fieldid = GetFieldID("bug_status");
|
|
|
|
SendSQL("INSERT INTO bugs_activity " .
|
2001-07-20 19:18:30 +04:00
|
|
|
"(bug_id,who,bug_when,fieldid,removed,added) VALUES " .
|
2000-02-17 08:15:23 +03:00
|
|
|
"($id,$who,now(),$fieldid,'$::unconfirmedstate','NEW')");
|
|
|
|
if (!$everconfirmed) {
|
|
|
|
$fieldid = GetFieldID("everconfirmed");
|
|
|
|
SendSQL("INSERT INTO bugs_activity " .
|
2001-07-20 19:18:30 +04:00
|
|
|
"(bug_id,who,bug_when,fieldid,removed,added) VALUES " .
|
2000-02-17 08:15:23 +03:00
|
|
|
"($id,$who,now(),$fieldid,'0','1')");
|
|
|
|
}
|
|
|
|
AppendComment($id, DBID_to_name($who),
|
|
|
|
"*** This bug has been confirmed by popular vote. ***");
|
|
|
|
print "<TABLE BORDER=1><TD><H2>Bug $id has been confirmed by votes.</H2>\n";
|
|
|
|
system("./processmail", $id);
|
|
|
|
print "<TD><A HREF=\"show_bug.cgi?id=$id\">Go To BUG# $id</A></TABLE>\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-05-25 23:22:31 +04:00
|
|
|
sub DumpBugActivity {
|
|
|
|
my ($id, $starttime) = (@_);
|
|
|
|
my $datepart = "";
|
2000-03-07 21:23:00 +03:00
|
|
|
|
|
|
|
die "Invalid id: $id" unless $id=~/^\s*\d+\s*$/;
|
|
|
|
|
1999-05-25 23:22:31 +04:00
|
|
|
if (defined $starttime) {
|
1999-09-15 21:25:28 +04:00
|
|
|
$datepart = "and bugs_activity.bug_when >= $starttime";
|
1999-05-25 23:22:31 +04:00
|
|
|
}
|
|
|
|
my $query = "
|
2001-08-31 07:54:37 +04:00
|
|
|
SELECT IFNULL(fielddefs.description, bugs_activity.fieldid),
|
|
|
|
bugs_activity.attach_id,
|
2000-01-23 00:43:30 +03:00
|
|
|
bugs_activity.bug_when,
|
2001-07-20 19:18:30 +04:00
|
|
|
bugs_activity.removed, bugs_activity.added,
|
1999-05-25 23:22:31 +04:00
|
|
|
profiles.login_name
|
2000-01-23 00:43:30 +03:00
|
|
|
FROM bugs_activity LEFT JOIN fielddefs ON
|
|
|
|
bugs_activity.fieldid = fielddefs.fieldid,
|
|
|
|
profiles
|
2000-01-22 07:24:42 +03:00
|
|
|
WHERE bugs_activity.bug_id = $id $datepart
|
|
|
|
AND profiles.userid = bugs_activity.who
|
|
|
|
ORDER BY bugs_activity.bug_when";
|
1999-05-25 23:22:31 +04:00
|
|
|
|
|
|
|
SendSQL($query);
|
|
|
|
|
2001-08-09 10:12:18 +04:00
|
|
|
# Instead of outright printing this, we are going to store it in a $html
|
|
|
|
# variable and print it and the end. This is so we can explain ? (if nesc.)
|
|
|
|
# at the top of the activity table rather than the botom.
|
|
|
|
my $html = "";
|
|
|
|
$html .= "<table border cellpadding=4>\n";
|
|
|
|
$html .= "<tr>\n";
|
|
|
|
$html .= " <th>Who</th><th>What</th><th>Removed</th><th>Added</th><th>When</th>\n";
|
|
|
|
$html .= "</tr>\n";
|
1999-05-25 23:22:31 +04:00
|
|
|
|
|
|
|
my @row;
|
2001-08-09 10:12:18 +04:00
|
|
|
my $incomplete_data = 0;
|
1999-05-25 23:22:31 +04:00
|
|
|
while (@row = FetchSQLData()) {
|
2001-08-31 07:54:37 +04:00
|
|
|
my ($field,$attachid,$when,$removed,$added,$who) = (@row);
|
|
|
|
$field =~ s/^Attachment/<a href="attachment.cgi?id=$attachid&action=view">Attachment #$attachid<\/a>/
|
|
|
|
if (Param('useattachmenttracker') && $attachid);
|
2001-07-20 19:18:30 +04:00
|
|
|
$removed = html_quote($removed);
|
|
|
|
$added = html_quote($added);
|
2001-07-30 16:52:21 +04:00
|
|
|
$removed = " " if $removed eq "";
|
|
|
|
$added = " " if $added eq "";
|
2001-08-09 10:12:18 +04:00
|
|
|
if ($added =~ /^\?/ || $removed =~ /^\?/) {
|
|
|
|
$incomplete_data = 1;
|
|
|
|
}
|
|
|
|
$html .= "<tr>\n";
|
|
|
|
$html .= "<td>$who</td>\n";
|
|
|
|
$html .= "<td>$field</td>\n";
|
|
|
|
$html .= "<td>$removed</td>\n";
|
|
|
|
$html .= "<td>$added</td>\n";
|
|
|
|
$html .= "<td>$when</td>\n";
|
|
|
|
$html .= "</tr>\n";
|
|
|
|
}
|
|
|
|
$html .= "</table>\n";
|
|
|
|
if ($incomplete_data) {
|
|
|
|
print "There was a bug in older versions of Bugzilla which caused activity data \n";
|
|
|
|
print "to be lost if there was a large number of cc's or dependencies. That \n";
|
|
|
|
print "has been fixed, however, there was some data already lost on this bug \n";
|
|
|
|
print "that could not be regenerated. The changes that the script could not \n";
|
|
|
|
print "reliably determine are prefixed by '?'\n";
|
|
|
|
print "<p>\n";
|
1999-05-25 23:22:31 +04:00
|
|
|
}
|
2001-08-09 10:12:18 +04:00
|
|
|
print $html;
|
1999-05-25 23:22:31 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-15 01:35:49 +03:00
|
|
|
sub GetCommandMenu {
|
|
|
|
my $loggedin = quietly_check_login();
|
2001-02-22 05:20:58 +03:00
|
|
|
my $html = "";
|
|
|
|
$html .= <<"--endquote--";
|
|
|
|
<FORM METHOD=GET ACTION="show_bug.cgi">
|
2001-03-11 01:06:57 +03:00
|
|
|
<TABLE width="100%"><TR><TD>
|
2001-02-22 05:20:58 +03:00
|
|
|
Actions:
|
2001-03-11 01:06:57 +03:00
|
|
|
</TD><TD VALIGN="middle" NOWRAP>
|
|
|
|
<a href='enter_bug.cgi'>New</a> | <a href='query.cgi'>Query</a> |
|
2001-02-22 05:20:58 +03:00
|
|
|
--endquote--
|
|
|
|
|
2000-01-15 01:35:49 +03:00
|
|
|
if (-e "query2.cgi") {
|
|
|
|
$html .= "[<a href='query2.cgi'>beta</a>]";
|
|
|
|
}
|
|
|
|
|
2000-01-24 08:50:46 +03:00
|
|
|
$html .=
|
2001-03-11 01:06:57 +03:00
|
|
|
qq{ <INPUT TYPE=SUBMIT VALUE="Find"> bug \# <INPUT NAME=id SIZE=6>};
|
2000-01-15 01:35:49 +03:00
|
|
|
|
2001-03-10 08:52:54 +03:00
|
|
|
$html .= " | <a href='reports.cgi'>Reports</a>";
|
|
|
|
if ($loggedin) {
|
|
|
|
if ($::anyvotesallowed) {
|
|
|
|
$html .= " | <A HREF=\"showvotes.cgi\">My votes</A>";
|
|
|
|
}
|
2001-03-11 01:06:57 +03:00
|
|
|
}
|
2000-01-15 01:35:49 +03:00
|
|
|
if ($loggedin) {
|
2001-02-22 05:20:58 +03:00
|
|
|
#a little mandatory SQL, used later on
|
2000-02-17 18:52:12 +03:00
|
|
|
SendSQL("SELECT mybugslink, userid, blessgroupset FROM profiles " .
|
|
|
|
"WHERE login_name = " . SqlQuote($::COOKIE{'Bugzilla_login'}));
|
|
|
|
my ($mybugslink, $userid, $blessgroupset) = (FetchSQLData());
|
2001-02-22 05:20:58 +03:00
|
|
|
|
|
|
|
#Begin settings
|
2001-03-11 01:06:57 +03:00
|
|
|
$html .= "</TD><TD> </TD><TD VALIGN=middle><NOBR>Edit <a href='userprefs.cgi'>prefs</a></NOBR>";
|
2000-01-15 01:35:49 +03:00
|
|
|
if (UserInGroup("tweakparams")) {
|
|
|
|
$html .= ", <a href=editparams.cgi>parameters</a>";
|
2000-01-15 02:30:24 +03:00
|
|
|
$html .= ", <a href=sanitycheck.cgi><NOBR>sanity check</NOBR></a>";
|
2000-01-15 01:35:49 +03:00
|
|
|
}
|
2000-02-17 18:52:12 +03:00
|
|
|
if (UserInGroup("editusers") || $blessgroupset) {
|
2000-01-18 21:34:01 +03:00
|
|
|
$html .= ", <a href=editusers.cgi>users</a>";
|
|
|
|
}
|
2000-01-15 01:35:49 +03:00
|
|
|
if (UserInGroup("editcomponents")) {
|
2000-01-17 22:54:50 +03:00
|
|
|
$html .= ", <a href=editproducts.cgi>components</a>";
|
2001-08-31 07:54:37 +04:00
|
|
|
$html .= ", <a href=editattachstatuses.cgi><NOBR>attachment statuses</NOBR></a>"
|
|
|
|
if Param('useattachmenttracker');
|
2000-01-15 01:35:49 +03:00
|
|
|
}
|
2000-04-26 23:35:51 +04:00
|
|
|
if (UserInGroup("creategroups")) {
|
|
|
|
$html .= ", <a href=editgroups.cgi>groups</a>";
|
|
|
|
}
|
2000-01-15 01:35:49 +03:00
|
|
|
if (UserInGroup("editkeywords")) {
|
2000-01-17 22:54:50 +03:00
|
|
|
$html .= ", <a href=editkeywords.cgi>keywords</a>";
|
2000-01-15 01:35:49 +03:00
|
|
|
}
|
2000-01-25 10:54:57 +03:00
|
|
|
$html .= " | <NOBR><a href=relogin.cgi>Log out</a> $::COOKIE{'Bugzilla_login'}</NOBR>";
|
2001-02-22 05:20:58 +03:00
|
|
|
$html .= "</TD></TR>";
|
|
|
|
|
|
|
|
#begin preset queries
|
|
|
|
my $mybugstemplate = Param("mybugstemplate");
|
|
|
|
my %substs;
|
|
|
|
$substs{'userid'} = url_quote($::COOKIE{"Bugzilla_login"});
|
|
|
|
if (!defined $::anyvotesallowed) {
|
|
|
|
GetVersionTable();
|
|
|
|
}
|
|
|
|
$html .= "</TR><TR>";
|
|
|
|
$html .= "<TD>Preset Queries: </TD>";
|
2001-03-11 01:06:57 +03:00
|
|
|
$html .= "<TD colspan=3>\n";
|
2001-02-22 05:20:58 +03:00
|
|
|
if ($mybugslink) {
|
|
|
|
my $mybugsurl = PerformSubsts($mybugstemplate, \%substs);
|
|
|
|
$html = $html . "<A HREF='$mybugsurl'><NOBR>My bugs</NOBR></A>";
|
|
|
|
}
|
|
|
|
SendSQL("SELECT name FROM namedqueries " .
|
|
|
|
"WHERE userid = $userid AND linkinfooter");
|
2001-03-11 01:06:57 +03:00
|
|
|
my $anynamedqueries = 0;
|
2001-02-22 05:20:58 +03:00
|
|
|
while (MoreSQLData()) {
|
|
|
|
my ($name) = (FetchSQLData());
|
2001-03-11 01:06:57 +03:00
|
|
|
if ($anynamedqueries || $mybugslink) { $html .= " | " }
|
|
|
|
$anynamedqueries = 1;
|
|
|
|
$html .= "<A HREF=\"buglist.cgi?&cmdtype=runnamed&namedcmd=" .
|
2001-02-22 05:20:58 +03:00
|
|
|
url_quote($name) . "\"><NOBR>$name</NOBR></A>";
|
|
|
|
}
|
|
|
|
$html .= "</TR>\n<TR>";
|
2000-01-15 01:35:49 +03:00
|
|
|
} else {
|
2001-03-11 01:06:57 +03:00
|
|
|
$html .= "</TD><TD> </TD><TD valign=middle align=right>\n";
|
2000-01-25 10:54:57 +03:00
|
|
|
$html .=
|
2001-03-11 01:06:57 +03:00
|
|
|
" <a href=\"createaccount.cgi\"><NOBR>New account</NOBR></a>\n";
|
2000-01-25 10:54:57 +03:00
|
|
|
$html .=
|
|
|
|
" | <NOBR><a href=query.cgi?GoAheadAndLogIn=1>Log in</a></NOBR>";
|
2001-02-22 05:20:58 +03:00
|
|
|
$html .= "</TD></TR>";
|
2000-01-15 01:35:49 +03:00
|
|
|
}
|
2001-02-22 05:20:58 +03:00
|
|
|
$html .= "</FORM>\n";
|
|
|
|
$html .= "</TABLE>";
|
2000-01-15 01:35:49 +03:00
|
|
|
return $html;
|
|
|
|
}
|
|
|
|
|
1998-09-16 01:49:26 +04:00
|
|
|
############# Live code below here (that is, not subroutine defs) #############
|
|
|
|
|
|
|
|
|
|
|
|
$| = 1;
|
|
|
|
|
|
|
|
# Uncommenting this next line can help debugging.
|
|
|
|
# print "Content-type: text/html\n\nHello mom\n";
|
|
|
|
|
|
|
|
# foreach my $k (sort(keys %ENV)) {
|
|
|
|
# print "$k $ENV{$k}<br>\n";
|
|
|
|
# }
|
|
|
|
|
|
|
|
if (defined $ENV{"REQUEST_METHOD"}) {
|
|
|
|
if ($ENV{"REQUEST_METHOD"} eq "GET") {
|
|
|
|
if (defined $ENV{"QUERY_STRING"}) {
|
|
|
|
$::buffer = $ENV{"QUERY_STRING"};
|
|
|
|
} else {
|
|
|
|
$::buffer = "";
|
|
|
|
}
|
1999-04-08 18:40:46 +04:00
|
|
|
ProcessFormFields $::buffer;
|
1998-09-16 01:49:26 +04:00
|
|
|
} else {
|
2000-03-31 03:56:36 +04:00
|
|
|
if (exists($ENV{"CONTENT_TYPE"}) && $ENV{"CONTENT_TYPE"} =~
|
1999-04-08 18:40:46 +04:00
|
|
|
m@multipart/form-data; boundary=\s*([^; ]+)@) {
|
|
|
|
ProcessMultipartFormFields($1);
|
|
|
|
$::buffer = "";
|
|
|
|
} else {
|
|
|
|
read STDIN, $::buffer, $ENV{"CONTENT_LENGTH"} ||
|
|
|
|
die "Couldn't get form data";
|
|
|
|
ProcessFormFields $::buffer;
|
|
|
|
}
|
1998-09-16 01:49:26 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (defined $ENV{"HTTP_COOKIE"}) {
|
|
|
|
foreach my $pair (split(/;/, $ENV{"HTTP_COOKIE"})) {
|
|
|
|
$pair = trim($pair);
|
|
|
|
if ($pair =~ /^([^=]*)=(.*)$/) {
|
|
|
|
$::COOKIE{$1} = $2;
|
|
|
|
} else {
|
|
|
|
$::COOKIE{$pair} = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|