diff --git a/src/gitolite.pm b/src/gitolite.pm index 5d51978..106624a 100644 --- a/src/gitolite.pm +++ b/src/gitolite.pm @@ -1,3 +1,4 @@ +use strict; # this file is commonly used using "require". It is not required to use "use" # (because it doesn't live in a different package) @@ -17,20 +18,23 @@ # common definitions # ---------------------------------------------------------------------------- -$ABRT = "\n\t\t***** ABORTING *****\n "; -$WARN = "\n\t\t***** WARNING *****\n "; +our $ABRT = "\n\t\t***** ABORTING *****\n "; +our $WARN = "\n\t\t***** WARNING *****\n "; # commands we're expecting -$R_COMMANDS=qr/^(git[ -]upload-pack|git[ -]upload-archive)$/; -$W_COMMANDS=qr/^git[ -]receive-pack$/; +our $R_COMMANDS=qr/^(git[ -]upload-pack|git[ -]upload-archive)$/; +our $W_COMMANDS=qr/^git[ -]receive-pack$/; # note that REPONAME_PATT allows "/", while USERNAME_PATT does not # also, the reason REPONAME_PATT is a superset of USERNAME_PATT is (duh!) # because in this version, a repo can have "CREATER" in the name (see docs) -$REPONAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@/+-]*$); # very simple pattern -$USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$); # very simple pattern +our $REPONAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@/+-]*$); # very simple pattern +our $USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$); # very simple pattern # same as REPONAME, plus some common regex metas -$REPOPATT_PATT=qr(^\@?[0-9a-zA-Z][\\^.$|()[\]*+?{}0-9a-zA-Z._\@/-]*$); +our $REPOPATT_PATT=qr(^\@?[0-9a-zA-Z][\\^.$|()[\]*+?{}0-9a-zA-Z._\@/-]*$); + +our $REPO_UMASK; +our %repos; # ---------------------------------------------------------------------------- # convenience subs @@ -78,6 +82,18 @@ sub check_ref { die "$perm $ref $repo $ENV{GL_USER} DENIED by fallthru\n"; } +# ln -sf :-) +sub ln_sf +{ + my($srcdir, $glob, $dstdir) = @_; + for my $hook ( glob("$srcdir/$glob") ) { + $hook =~ s/$srcdir\///; + unlink "$dstdir/$hook"; + symlink "$srcdir/$hook", "$dstdir/$hook" or die "could not symlink $hook\n"; + } +} + + # ---------------------------------------------------------------------------- # where is the rc file hiding? # ---------------------------------------------------------------------------- @@ -128,7 +144,7 @@ sub new_repo system("git", "config", "gitweb.owner", $creater); } # propagate our own, plus any local admin-defined, hooks - system("cp $hooks_dir/* hooks/"); + ln_sf($hooks_dir, "*", "hooks"); chmod 0755, "hooks/update"; } @@ -321,7 +337,7 @@ sub expand_wild sub special_cmd { - my ($GL_ADMINDIR, $GL_CONF_COMPILED, $RSYNC_BASE, $HTPASSWD_FILE) = @_; + my ($GL_ADMINDIR, $GL_CONF_COMPILED, $shell_allowed, $RSYNC_BASE, $HTPASSWD_FILE) = @_; my $cmd = $ENV{SSH_ORIGINAL_COMMAND}; my $user = $ENV{GL_USER}; diff --git a/src/gl-auth-command b/src/gl-auth-command index dc6aca5..3628c19 100755 --- a/src/gl-auth-command +++ b/src/gl-auth-command @@ -147,7 +147,7 @@ if ($ENV{SSH_ORIGINAL_COMMAND} =~ $CUSTOM_COMMANDS) { my ($verb, $repo) = ($ENV{SSH_ORIGINAL_COMMAND} =~ /^\s*(git\s+\S+|\S+)\s+'\/?(.*?)(?:\.git)?'/); unless ( $verb and ( $verb =~ $R_COMMANDS or $verb =~ $W_COMMANDS ) and $repo and $repo =~ $REPONAME_PATT ) { # ok, it's not a normal git command; call the special command helper - &special_cmd ($GL_ADMINDIR, $GL_CONF_COMPILED, $RSYNC_BASE, $HTPASSWD_FILE); + &special_cmd ($GL_ADMINDIR, $GL_CONF_COMPILED, $shell_allowed, $RSYNC_BASE, $HTPASSWD_FILE); exit; } die "$repo ends with a slash; I don't like that\n" if $repo =~ /\/$/; diff --git a/src/gl-compile-conf b/src/gl-compile-conf index 00fa298..5c19ebb 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -539,5 +539,6 @@ close $newkeys_fh or die "$ABRT close newkeys failed: $!\n"; # all done; overwrite the file (use cat to avoid perm changes) system("cat $ENV{HOME}/.ssh/authorized_keys > $ENV{HOME}/.ssh/old_authkeys"); -system("cat $ENV{HOME}/.ssh/new_authkeys > $ENV{HOME}/.ssh/authorized_keys"); +system("cat $ENV{HOME}/.ssh/new_authkeys > $ENV{HOME}/.ssh/authorized_keys") + and die "couldn't write authkeys file\n"; system("rm $ENV{HOME}/.ssh/new_authkeys"); diff --git a/src/gl-install b/src/gl-install index 9494fc6..9159ed5 100755 --- a/src/gl-install +++ b/src/gl-install @@ -71,14 +71,16 @@ chdir("$repo_base_abs") or die "chdir $repo_base_abs failed: $!\n"; for my $repo (`find . -type d -name "*.git"`) { chomp ($repo); # propagate our own, plus any local admin-defined, hooks - system("cp $GL_ADMINDIR/src/hooks/* $repo/hooks/"); + ln_sf("$GL_ADMINDIR/src/hooks", "*", "$repo/hooks"); chmod 0755, "$repo/hooks/update"; } # oh and one of those repos is a bit more special and has an extra hook :) if ( -d "gitolite-admin.git/hooks" ) { print "copying post-update hook to gitolite-admin repo...\n"; - system("cp $GL_ADMINDIR/src/ga-post-update-hook gitolite-admin.git/hooks/post-update"); + unlink "gitolite-admin.git/hooks/post-update"; + symlink "$GL_ADMINDIR/src/ga-post-update-hook", "gitolite-admin.git/hooks/post-update" + or die "could not symlink post-update hook\n"; chmod 0755, "gitolite-admin.git/hooks/post-update"; }