summaryrefslogtreecommitdiffstats
path: root/docs
ModeNameSize
-rw-r--r--.cvsignore9logstatsplain
-rw-r--r--BUGS420logstatsplain
-rw-r--r--COPYING18007logstatsplain
-rw-r--r--HACKING3824logstatsplain
-rw-r--r--README15725logstatsplain
-rw-r--r--README.devel9850logstatsplain
-rw-r--r--README.pxe5872logstatsplain
-rw-r--r--SHORTCUTS1464logstatsplain
-rw-r--r--TODO17444logstatsplain
-rw-r--r--advocacy3122logstatsplain
-rw-r--r--advocacy-interactive1752logstatsplain
-rw-r--r--comparisons3040logstatsplain
-rw-r--r--diskdrake.TODO1127logstatsplain
d---------drakfont288logstatsplain
-rw-r--r--draknet_advanced_doc.txt7633logstatsplain
-rw-r--r--mdk-vs-redhat1381logstatsplain
-rw-r--r--net_object_class.fig2684logstatsplain
-rw-r--r--object_class.fig1026logstatsplain
-rw-r--r--wizard.doc1082logstatsplain
a> 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
# -*- 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): Bradley Baetz <bbaetz@student.usyd.edu.au>
#                 Erik Stambaugh <erik@dasbistro.com>
#                 A. Karl Kornel <karl@kornel.name>

package Bugzilla;

use strict;

use Bugzilla::Config;
use Bugzilla::Constants;
use Bugzilla::Auth;
use Bugzilla::Auth::Persist::Cookie;
use Bugzilla::CGI;
use Bugzilla::DB;
use Bugzilla::Template;
use Bugzilla::User;
use Bugzilla::Error;
use Bugzilla::Util;
use Bugzilla::Field;

use File::Basename;
use Safe;

# This creates the request cache for non-mod_perl installations.
our $_request_cache = {};

#####################################################################
# Constants
#####################################################################

# Scripts that are not stopped by shutdownhtml being in effect.
use constant SHUTDOWNHTML_EXEMPT => [
    'editparams.cgi',
    'checksetup.pl',
];

# Non-cgi scripts that should silently exit.
use constant SHUTDOWNHTML_EXIT_SILENTLY => [
    'whine.pl'
];

#####################################################################
# Global Code
#####################################################################

# The following subroutine is for debugging purposes only.
# Uncommenting this sub and the $::SIG{__DIE__} trap underneath it will
# cause any fatal errors to result in a call stack trace to help track
# down weird errors.
#
#sub die_with_dignity {
#    use Carp ();
#    my ($err_msg) = @_;
#    print $err_msg;
#    Carp::confess($err_msg);
#}
#$::SIG{__DIE__} = \&Bugzilla::die_with_dignity;

# Some environment variables are not taint safe
delete @::ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

# If Bugzilla is shut down, do not allow anything to run, just display a
# message to the user about the downtime and log out.  Scripts listed in 
# SHUTDOWNHTML_EXEMPT are exempt from this message.
#
# Because this is code which is run live from perl "use" commands of other
# scripts, we're skipping this part if we get here during a perl syntax check
# -- runtests.pl compiles scripts without running them, so we need to make sure
# that this check doesn't apply to 'perl -c' calls.
#
# This code must go here. It cannot go anywhere in Bugzilla::CGI, because
# it uses Template, and that causes various dependency loops.
if (!$^C
    && Bugzilla->params->{"shutdownhtml"}
    && lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1) 
{
    # Allow non-cgi scripts to exit silently (without displaying any
    # message), if desired. At this point, no DBI call has been made
    # yet, and no error will be returned if the DB is inaccessible.
    if (lsearch(SHUTDOWNHTML_EXIT_SILENTLY, basename($0)) > -1
        && !i_am_cgi())
    {
        exit;
    }

    # For security reasons, log out users when Bugzilla is down.
    # Bugzilla->login() is required to catch the logincookie, if any.
    my $user = Bugzilla->login(LOGIN_OPTIONAL);
    my $userid = $user->id;
    Bugzilla->logout();

    my $template = Bugzilla->template;
    my $vars = {};
    $vars->{'message'} = 'shutdown';
    $vars->{'userid'} = $userid;
    # Generate and return a message about the downtime, appropriately
    # for if we're a command-line script or a CGI script.
    my $extension;
    if (i_am_cgi() && (!Bugzilla->cgi->param('ctype')
                       || Bugzilla->cgi->param('ctype') eq 'html')) {
        $extension = 'html';
    }
    else {
        $extension = 'txt';
    }
    print Bugzilla->cgi->header() if i_am_cgi();
    my $t_output;
    $template->process("global/message.$extension.tmpl", $vars, \$t_output)
        || ThrowTemplateError($template->error);
    print $t_output . "\n";
    exit;
}

#####################################################################
# Subroutines and Methods
#####################################################################

sub template {
    my $class = shift;
    request_cache()->{template} ||= Bugzilla::Template->create();
    return request_cache()->{template};
}

sub cgi {
    my $class = shift;
    request_cache()->{cgi} ||= new Bugzilla::CGI();
    return request_cache()->{cgi};
}

sub params {
    my $class = shift;
    request_cache()->{params} ||= Bugzilla::Config::read_param_file();
    return request_cache()->{params};
}

sub user {
    my $class = shift;
    request_cache()->{user} ||= new Bugzilla::User;
    return request_cache()->{user};
}

sub sudoer {
    my $class = shift;    
    return request_cache()->{sudoer};
}

sub sudo_request {
    my $class = shift;
    my $new_user = shift;
    my $new_sudoer = shift;

    request_cache()->{user}   = $new_user;
    request_cache()->{sudoer} = $new_sudoer;

    # NOTE: If you want to log the start of an sudo session, do it here.

    return;
}

sub login {
    my ($class, $type) = @_;

    my $authorizer = new Bugzilla::Auth();
    $type = LOGIN_REQUIRED if Bugzilla->cgi->param('GoAheadAndLogIn');
    if (!defined $type || $type == LOGIN_NORMAL) {
        $type = Bugzilla->params->{'requirelogin'} ? LOGIN_REQUIRED : LOGIN_NORMAL;
    }
    my $authenticated_user = $authorizer->login($type);
    
    # At this point, we now know if a real person is logged in.
    # We must now check to see if an sudo session is in progress.
    # For a session to be in progress, the following must be true:
    # 1: There must be a logged in user
    # 2: That user must be in the 'bz_sudoer' group
    # 3: There must be a valid value in the 'sudo' cookie
    # 4: A Bugzilla::User object must exist for the given cookie value
    # 5: That user must NOT be in the 'bz_sudo_protect' group
    my $sudo_cookie = $class->cgi->cookie('sudo');
    detaint_natural($sudo_cookie) if defined($sudo_cookie);
    my $sudo_target;
    $sudo_target = new Bugzilla::User($sudo_cookie) if defined($sudo_cookie);
    if (defined($authenticated_user)                 &&
        $authenticated_user->in_group('bz_sudoers')  &&
        defined($sudo_cookie)                        &&
        defined($sudo_target)                        &&
        !($sudo_target->in_group('bz_sudo_protect'))
       )
    {
        request_cache()->{user}   = $sudo_target;
        request_cache()->{sudoer} = $authenticated_user;
        # And make sure that both users have the same Auth object,
        # since we never call Auth::login for the sudo target.
        $sudo_target->set_authorizer($authenticated_user->authorizer);

        # NOTE: If you want to do any special logging, do it here.
    }
    else {
        request_cache()->{user} = $authenticated_user;
    }
    
    return request_cache()->{user};
}

sub logout {
    my ($class, $option) = @_;

    # If we're not logged in, go away
    return unless user->id;

    $option = LOGOUT_CURRENT unless defined $option;
    Bugzilla::Auth::Persist::Cookie->logout({type => $option});
    Bugzilla->logout_request() unless $option eq LOGOUT_KEEP_CURRENT;
}

sub logout_user {
    my ($class, $user) = @_;
    # When we're logging out another user we leave cookies alone, and
    # therefore avoid calling Bugzilla->logout() directly.
    Bugzilla::Auth::Persist::Cookie->logout({user => $user});
}

# just a compatibility front-end to logout_user that gets a user by id
sub logout_user_by_id {
    my ($class, $id) = @_;
    my $user = new Bugzilla::User($id);
    $class->logout_user($user);
}

# hack that invalidates credentials for a single request
sub logout_request {
    delete request_cache()->{user};
    delete request_cache()->{sudoer};
    # We can't delete from $cgi->cookie, so logincookie data will remain
    # there. Don't rely on it: use Bugzilla->user->login instead!
}

sub dbh {
    my $class = shift;

    # If we're not connected, then we must want the main db
    request_cache()->{dbh} ||= request_cache()->{dbh_main} 
        = Bugzilla::DB::connect_main();

    return request_cache()->{dbh};
}

sub batch {
    my $class = shift;
    my $newval = shift;
    if ($newval) {
        request_cache()->{batch} = $newval;
    }
    return request_cache()->{batch} || 0;
}

sub switch_to_shadow_db {
    my $class = shift;

    if (!request_cache()->{dbh_shadow}) {
        if (Bugzilla->params->{'shadowdb'}) {
            request_cache()->{dbh_shadow} = Bugzilla::DB::connect_shadow();
        } else {
            request_cache()->{dbh_shadow} = request_cache()->{dbh_main};
        }
    }

    request_cache()->{dbh} = request_cache()->{dbh_shadow};