948f700c7a
This new adc allows you to run arbitrary git commands on the server. It is disabled by default, and you have to READ ALL INSTRUCTIONS **AND** SOURCE CODE BEFORE DEPLOYING.
124 lines
4.3 KiB
Perl
Executable file
124 lines
4.3 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
|
|
# READ ALL INSTRUCTIONS **AND** SOURCE CODE BEFORE DEPLOYING.
|
|
|
|
# run arbitrary git commands on the server
|
|
|
|
# ----
|
|
|
|
# WARNING: HIGHLY INFLAMMABLE. FISSILE MATERIAL, RADIATION HAZARD. HANDLE
|
|
# WITH CARE. DO NOT REMOVE MANUFACTURER LABEL. NOT TO BE USED WHILE DRIVING
|
|
# OR UNDER THE INFLUENCE OF ALCOHOL. PATIENTS WITH HEART PROBLEMS MUST SEE
|
|
# THEIR CARDIOLOGIST BEFORE USING.
|
|
|
|
# ----
|
|
|
|
# ok, warnings done, here's the saner description.
|
|
#
|
|
# This ADC lets you run arbirtrary git commands on any repo on the server.
|
|
# The first argument will be the repo name, the second and subsequent
|
|
# arguments will be the rest of the git command. For example, to run `git
|
|
# describe --tags` on repo `foo`, you would run:
|
|
#
|
|
# ssh git@server git foo describe --tags
|
|
#
|
|
# If that looks weird to you, you can use
|
|
#
|
|
# ssh git@server git --repo=foo describe --tags
|
|
#
|
|
# (the position remains the same: between 'git' and '<command>')
|
|
|
|
# SECURITY AND SAFETY NOTES:
|
|
#
|
|
# - ADC arguments are checked (in `sub try_adc`) to fit `ADC_CMD_ARGS_PATT`
|
|
# and the only special characters allowed by that pattern are ".", "_", "@",
|
|
# "/", "+", ":", and "-". Thus, *this* adc does not check arguments
|
|
# anymore. ANY RISK IN THIS LAXITY IS YOURS, NOT MINE, although I believe
|
|
# it is safe enough.
|
|
#
|
|
# - Most commands don't make sense to allow, even among those that do not
|
|
# require a work-tree. Avoid commands that can be done using normal git
|
|
# remote access (ls-remote, clone, archive, push, etc). Also, avoid
|
|
# commands that *write* to the repo if possible, or at least think/test
|
|
# thoroughly before enabling them.
|
|
#
|
|
# - You have to deal with issues like stdin/out, output files created etc.,
|
|
# which is another reason to avoid most of the more complex commands.
|
|
#
|
|
# - Do not enable prune, gc, etc., if your repos are on NFS/CIFS/etc. See
|
|
# http://permalink.gmane.org/gmane.comp.version-control.git/122670 for why.
|
|
#
|
|
# - The list of commands allowed to be executed, and the permissions required
|
|
# to do so, are defined here. Feel free to uncomment any of this to make
|
|
# things more relaxed. If you add new ones, note that the permissions can
|
|
# only be 'R', 'W', or 'A'. The meanings of R and W are obvious; "A" means
|
|
# the user must have write access to the *gitolite-admin* repo to run this
|
|
# command -- yeah that's a nice twist innit? ;-)
|
|
|
|
my %GIT_COMMANDS = (
|
|
# annotate => 'R',
|
|
# blame => 'R',
|
|
'count-objects' => 'R',
|
|
describe => 'R',
|
|
# diff => 'R',
|
|
# 'fast-export' => 'R',
|
|
# grep => 'R',
|
|
# log => 'R',
|
|
# shortlog => 'R',
|
|
# 'show-branch' => 'R',
|
|
# show => 'R',
|
|
# whatchanged => 'R',
|
|
|
|
# config => 'A', # I strongly discourage un-commenting this
|
|
# fsck => 'W', # write access required
|
|
# gc => 'W', # write access required
|
|
# prune => 'A', # admin access required
|
|
# repack => 'A', # admin access required
|
|
);
|
|
|
|
# preliminary stuff; indented just to visually get it out of the way
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
die "ENV GL_RC not set\n" unless $ENV{GL_RC};
|
|
die "ENV GL_BINDIR not set\n" unless $ENV{GL_BINDIR};
|
|
|
|
unshift @INC, $ENV{GL_BINDIR};
|
|
require gitolite or die "parse gitolite.pm failed\n";
|
|
gitolite->import;
|
|
|
|
my $no_help = "this command is too dangerous to just show a help message; we don't want anyone\nrunning it without reading the source and understanding the implications!\n";
|
|
|
|
# get the repo name
|
|
my $repo = shift or die $no_help;
|
|
$repo =~ s/^--repo=//;
|
|
$repo =~ s/\.git$//;
|
|
# get the command
|
|
my $cmd = shift or die $no_help;
|
|
|
|
# is it a valid command at all?
|
|
exists $GIT_COMMANDS{$cmd} or die "invalid git command\n";
|
|
|
|
# check access
|
|
my $aa = $GIT_COMMANDS{$cmd}; # aa == attempted access
|
|
if ($aa eq 'A') {
|
|
my ($perm, $creator) = check_access('gitolite-admin');
|
|
$perm =~ /W/ or die "no admin access\n";
|
|
} else {
|
|
my ($perm, $creator) = check_access($repo);
|
|
$perm =~ /$aa/ or die "no $aa access to $repo\n";
|
|
}
|
|
|
|
# cd to the repo dir
|
|
chdir("$ENV{GL_REPO_BASE_ABS}/$repo.git") or die "chdir failed: $!\n";
|
|
|
|
# remove or comment the below line to signify you have read and understood all this
|
|
die $no_help;
|
|
|
|
# now run the git command... fingers crossed
|
|
|
|
unshift @ARGV, "git", $cmd;
|
|
print STDERR "+ ", join(" ", @ARGV), "\n";
|
|
exec @ARGV;
|