Merge branch 'master' into wildrepos
lots of conflicts, esp in gl-auth-command, due to refactoring the "special commands" stuff on master Conflicts: doc/3-faq-tips-etc.mkd src/gitolite.pm src/gl-auth-command src/gl-compile-conf
This commit is contained in:
commit
c43560d2ef
7 changed files with 279 additions and 75 deletions
114
src/gitolite.pm
114
src/gitolite.pm
|
@ -292,4 +292,118 @@ sub expand_wild
|
|||
}
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# S P E C I A L C O M M A N D S
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
sub special_cmd
|
||||
{
|
||||
my ($GL_ADMINDIR, $GL_CONF_COMPILED, $RSYNC_BASE, $HTPASSWD_FILE) = @_;
|
||||
|
||||
my $cmd = $ENV{SSH_ORIGINAL_COMMAND};
|
||||
my $user = $ENV{GL_USER};
|
||||
|
||||
# check each special command we know about and call it if enabled
|
||||
if ($cmd eq 'info') {
|
||||
&report_basic($GL_ADMINDIR, $GL_CONF_COMPILED, $user);
|
||||
print "you also have shell access\n\r" if $shell_allowed;
|
||||
} elsif ($HTPASSWD_FILE and $cmd eq 'htpasswd') {
|
||||
&ext_cmd_htpasswd($HTPASSWD_FILE);
|
||||
} elsif ($RSYNC_BASE and $cmd =~ /^rsync /) {
|
||||
&ext_cmd_rsync($GL_CONF_COMPILED, $RSYNC_BASE, $cmd);
|
||||
} else {
|
||||
# if the user is allowed a shell, just run the command
|
||||
exec $ENV{SHELL}, "-c", $cmd if $shell_allowed;
|
||||
|
||||
die "bad command: $cmd\n";
|
||||
}
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# generic check access routine
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
sub check_access
|
||||
{
|
||||
my ($GL_CONF_COMPILED, $repo, $path, $perm) = @_;
|
||||
my $ref = "NAME/$path";
|
||||
|
||||
&parse_acl($GL_CONF_COMPILED);
|
||||
|
||||
# until I do some major refactoring (which will bloat the update hook a
|
||||
# bit, sadly), this code duplicates stuff in the current update hook.
|
||||
|
||||
my @allowed_refs;
|
||||
# we want specific perms to override @all, so they come first
|
||||
push @allowed_refs, @ { $repos{$repo}{$ENV{GL_USER}} || [] };
|
||||
push @allowed_refs, @ { $repos{$repo}{'@all'} || [] };
|
||||
|
||||
for my $ar (@allowed_refs) {
|
||||
my $refex = (keys %$ar)[0];
|
||||
next unless $ref =~ /^$refex/;
|
||||
die "$perm $ref $ENV{GL_USER} DENIED by $refex\n" if $ar->{$refex} eq '-';
|
||||
return if ($ar->{$refex} =~ /\Q$perm/);
|
||||
}
|
||||
die "$perm $ref $ENV{GL_REPO} $ENV{GL_USER} DENIED by fallthru\n";
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# external command helper: rsync
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
sub ext_cmd_rsync
|
||||
{
|
||||
my ($GL_CONF_COMPILED, $RSYNC_BASE, $cmd) = @_;
|
||||
|
||||
# test the command patterns; reject if they don't fit. Rsync sends
|
||||
# commands that looks like one of these to the server (the first one is
|
||||
# for a read, the second for a write)
|
||||
# rsync --server --sender -some.flags . some/path
|
||||
# rsync --server -some.flags . some/path
|
||||
|
||||
die "bad rsync command: $cmd"
|
||||
unless $cmd =~ /^rsync --server( --sender)? -[\w.]+(?: --(?:delete|partial))* \. (\S+)$/;
|
||||
my $perm = "W";
|
||||
$perm = "R" if $1;
|
||||
my $path = $2;
|
||||
die "I dont like absolute paths in $cmd\n" if $path =~ /^\//;
|
||||
die "I dont like '..' paths in $cmd\n" if $path =~ /\.\./;
|
||||
|
||||
# ok now check if we're permitted to execute a $perm action on $path
|
||||
# (taken as a refex) using rsync.
|
||||
|
||||
&check_access($GL_CONF_COMPILED, 'EXTCMD/rsync', $path, $perm);
|
||||
# that should "die" if there's a problem
|
||||
|
||||
wrap_chdir($RSYNC_BASE);
|
||||
&log_it("$ENV{GL_TS}\t$ENV{SSH_ORIGINAL_COMMAND}\t$ENV{USER}\n");
|
||||
exec $ENV{SHELL}, "-c", $ENV{SSH_ORIGINAL_COMMAND};
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# external command helper: htpasswd
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
sub ext_cmd_htpasswd
|
||||
{
|
||||
my $HTPASSWD_FILE = shift;
|
||||
|
||||
die "$HTPASSWD_FILE doesn't exist or is not writable\n" unless -w $HTPASSWD_FILE;
|
||||
$|++;
|
||||
print <<EOFhtp;
|
||||
Please type in your new htpasswd at the prompt. You only have to type it once.
|
||||
|
||||
NOTE THAT THE PASSWORD WILL BE ECHOED, so please make sure no one is
|
||||
shoulder-surfing, and make sure you clear your screen as well as scrollback
|
||||
history after you're done (or close your terminal instance).
|
||||
|
||||
EOFhtp
|
||||
print "new htpasswd:";
|
||||
|
||||
my $password = <>;
|
||||
$password =~ s/[\n\r]*$//;
|
||||
my $rc = system("htpasswd", "-b", $HTPASSWD_FILE, $ENV{GL_USER}, $password);
|
||||
die "htpasswd command seems to have failed with $rc return code...\n" if $rc;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue