📄 filesystem.pm
字号:
# -*- 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.## Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org># Bill Barry <after.fallout@gmail.com>package Bugzilla::Install::Filesystem;# NOTE: This package may "use" any modules that it likes,# and localconfig is available. However, all functions in this# package should assume that:## * Templates are not available.# * Files do not have the correct permissions.# * The database does not exist.use strict;use Bugzilla::Constants;use Bugzilla::Error;use Bugzilla::Install::Localconfig;use Bugzilla::Util;use File::Find;use File::Path;use File::Basename;use IO::File;use POSIX ();use base qw(Exporter);our @EXPORT = qw( update_filesystem create_htaccess fix_all_file_permissions);# This looks like a constant because it effectively is, but# it has to call other subroutines and read the current filesystem,# so it's defined as a sub. This is not exported, so it doesn't have# a perldoc. However, look at the various hashes defined inside this # function to understand what it returns. (There are comments throughout.)## The rationale for the file permissions is that the web server generally # runs as apache, so the cgi scripts should not be writable for apache,# otherwise someone may find it possible to change the cgis when exploiting# some security flaw somewhere (not necessarily in Bugzilla!)sub FILESYSTEM { my $datadir = bz_locations()->{'datadir'}; my $attachdir = bz_locations()->{'attachdir'}; my $extensionsdir = bz_locations()->{'extensionsdir'}; my $webdotdir = bz_locations()->{'webdotdir'}; my $templatedir = bz_locations()->{'templatedir'}; my $libdir = bz_locations()->{'libpath'}; my $skinsdir = bz_locations()->{'skinsdir'}; my $ws_group = Bugzilla->localconfig->{'webservergroup'}; # The set of permissions that we use: # FILES # Executable by the web server my $ws_executable = $ws_group ? 0750 : 0755; # Executable by the owner only. my $owner_executable = 0700; # Readable by the web server. my $ws_readable = $ws_group ? 0640 : 0644; # Readable by the owner only. my $owner_readable = 0600; # Writeable by the web server. my $ws_writeable = $ws_group ? 0660 : 0666; # DIRECTORIES # Readable by the web server. my $ws_dir_readable = $ws_group ? 0750 : 0755; # Readable only by the owner. my $owner_dir_readable = 0700; # Writeable by the web server. my $ws_dir_writeable = $ws_group ? 0770 : 01777; # The webserver can overwrite files owned by other users, # in this directory. my $ws_dir_full_control = $ws_group ? 0770 : 0777; # Note: When being processed by checksetup, these have their permissions # set in this order: %all_dirs, %recurse_dirs, %all_files. # # Each is processed in alphabetical order of keys, so shorter keys # will have their permissions set before longer keys (thus setting # the permissions on parent directories before setting permissions # on their children). # --- FILE PERMISSIONS (Non-created files) --- # my %files = ( '*' => { perms => $ws_readable }, '*.cgi' => { perms => $ws_executable }, 'whineatnews.pl' => { perms => $ws_executable }, 'collectstats.pl' => { perms => $ws_executable }, 'checksetup.pl' => { perms => $owner_executable }, 'importxml.pl' => { perms => $ws_executable }, 'runtests.pl' => { perms => $owner_executable }, 'testserver.pl' => { perms => $ws_executable }, 'whine.pl' => { perms => $ws_executable }, 'customfield.pl' => { perms => $owner_executable }, 'email_in.pl' => { perms => $ws_executable }, 'docs/makedocs.pl' => { perms => $owner_executable }, 'docs/rel_notes.txt' => { perms => $ws_readable }, 'docs/README.docs' => { perms => $owner_readable }, "$datadir/bugzilla-update.xml" => { perms => $ws_writeable }, "$datadir/params" => { perms => $ws_writeable }, "$datadir/mailer.testfile" => { perms => $ws_writeable }, ); # Directories that we want to set the perms on, but not # recurse through. These are directories we didn't create # in checkesetup.pl. my %non_recurse_dirs = ( '.' => $ws_dir_readable, docs => $ws_dir_readable, ); # This sets the permissions for each item inside each of these # directories, including the directory itself. # 'CVS' directories are special, though, and are never readable by # the webserver. my %recurse_dirs = ( # Writeable directories "$datadir/template" => { files => $ws_readable, dirs => $ws_dir_full_control }, $attachdir => { files => $ws_writeable, dirs => $ws_dir_writeable }, $webdotdir => { files => $ws_writeable, dirs => $ws_dir_writeable }, graphs => { files => $ws_writeable, dirs => $ws_dir_writeable }, # Readable directories "$datadir/mining" => { files => $ws_readable, dirs => $ws_dir_readable }, "$datadir/duplicates" => { files => $ws_readable, dirs => $ws_dir_readable }, "$libdir/Bugzilla" => { files => $ws_readable, dirs => $ws_dir_readable }, $templatedir => { files => $ws_readable, dirs => $ws_dir_readable }, $extensionsdir => { files => $ws_readable, dirs => $ws_dir_readable }, images => { files => $ws_readable, dirs => $ws_dir_readable }, css => { files => $ws_readable, dirs => $ws_dir_readable }, js => { files => $ws_readable, dirs => $ws_dir_readable }, skins => { files => $ws_readable, dirs => $ws_dir_readable }, t => { files => $owner_readable, dirs => $owner_dir_readable }, 'docs/html' => { files => $ws_readable, dirs => $ws_dir_readable }, 'docs/pdf' => { files => $ws_readable, dirs => $ws_dir_readable }, 'docs/txt' => { files => $ws_readable, dirs => $ws_dir_readable }, 'docs/images' => { files => $ws_readable, dirs => $ws_dir_readable }, 'docs/lib' => { files => $owner_readable, dirs => $owner_dir_readable }, 'docs/xml' => { files => $owner_readable, dirs => $owner_dir_readable }, ); # --- FILES TO CREATE --- # # The name of each directory that we should actually *create*, # pointing at its default permissions. my %create_dirs = ( $datadir => $ws_dir_full_control, "$datadir/mimedump-tmp" => $ws_dir_writeable, "$datadir/mining" => $ws_dir_readable, "$datadir/duplicates" => $ws_dir_readable, $attachdir => $ws_dir_writeable, $extensionsdir => $ws_dir_readable, graphs => $ws_dir_writeable, $webdotdir => $ws_dir_writeable, 'skins/custom' => $ws_dir_readable, 'skins/contrib' => $ws_dir_readable, ); # The name of each file, pointing at its default permissions and # default contents. my %create_files = ( "$datadir/mail" => { perms => $ws_readable }, ); # Each standard stylesheet has an associated custom stylesheet that # we create. Also, we create placeholders for standard stylesheets # for contrib skins which don't provide them themselves. foreach my $skin_dir ("$skinsdir/custom", <$skinsdir/contrib/*>) { next unless -d $skin_dir; next if basename($skin_dir) =~ /^cvs$/i; foreach (<$skinsdir/standard/*.css>) { my $standard_css_file = basename($_); my $custom_css_file = "$skin_dir/$standard_css_file"; $create_files{$custom_css_file} = { perms => $ws_readable, contents => <<EOT/* * Custom rules for $standard_css_file. * The rules you put here override rules in that stylesheet. */EOT } } } # Because checksetup controls the creation of index.html separately # from all other files, it gets its very own hash. my %index_html = ( 'index.html' => { perms => $ws_readable, contents => <<EOT<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head> <meta http-equiv="Refresh" content="0; URL=index.cgi"></head><body> <h1>I think you are looking for <a href="index.cgi">index.cgi</a></h1></body></html>EOT } ); # Because checksetup controls the .htaccess creation separately # by a localconfig variable, these go in a separate variable from # %create_files. my $ht_default_deny = <<EOT;# nothing in this directory is retrievable unless overridden by an .htaccess# in a subdirectorydeny from allEOT my %htaccess = ( "$attachdir/.htaccess" => { perms => $ws_readable, contents => $ht_default_deny }, "$libdir/Bugzilla/.htaccess" => { perms => $ws_readable, contents => $ht_default_deny }, "$templatedir/.htaccess" => { perms => $ws_readable, contents => $ht_default_deny }, '.htaccess' => { perms => $ws_readable, contents => <<EOT# Don't allow people to retrieve non-cgi executable files or our private data<FilesMatch ^(.*\\.pm|.*\\.pl|.*localconfig.*)\$> deny from all</FilesMatch>EOT }, "$webdotdir/.htaccess" => { perms => $ws_readable, contents => <<EOT# Restrict access to .dot files to the public webdot server at research.att.com# if research.att.com ever changes their IP, or if you use a different# webdot server, you'll need to edit this<FilesMatch \\.dot\$> Allow from 192.20.225.0/24 Deny from all</FilesMatch># Allow access to .png files created by a local copy of 'dot'<FilesMatch \\.png\$> Allow from all</FilesMatch># And no directory listings, either.Deny from allEOT }, # Even though $datadir may not (and should not) be in the webtree, # we can't know for sure, so create the .htaccess anyway. It's harmless # if it's not accessible... "$datadir/.htaccess" => { perms => $ws_readable, contents => <<EOT# Nothing in this directory is retrievable unless overridden by an .htaccess# in a subdirectory; the only exception is duplicates.rdf, which is used by# duplicates.xul and must be loadable over the webdeny from all<Files duplicates.rdf> allow from all</Files>EOT }, ); my %all_files = (%create_files, %htaccess, %index_html, %files); my %all_dirs = (%create_dirs, %non_recurse_dirs); return { create_dirs => \%create_dirs, recurse_dirs => \%recurse_dirs, all_dirs => \%all_dirs, create_files => \%create_files, htaccess => \%htaccess, index_html => \%index_html, all_files => \%all_files, };}sub update_filesystem { my ($params) = @_; my $fs = FILESYSTEM(); my %dirs = %{$fs->{create_dirs}}; my %files = %{$fs->{create_files}}; my $datadir = bz_locations->{'datadir'}; # If the graphs/ directory doesn't exist, we're upgrading from # a version old enough that we need to update the $datadir/mining # format. if (-d "$datadir/mining" && !-d 'graphs') { _update_old_charts($datadir); } # By sorting the dirs, we assure that shorter-named directories # (meaning parent directories) are always created before their # child directories. foreach my $dir (sort keys %dirs) { unless (-d $dir) { print "Creating $dir directory...\n"; mkdir $dir || die $!; # For some reason, passing in the permissions to "mkdir" # doesn't work right, but doing a "chmod" does.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -