3 # Abort any push early if the pushing user doesn't have any push permissions
4 # at all. This avoids unnecessary traffic and unpacked object pollution.
6 # This script is intended for use from within the chroot jail and may or may
7 # not work properly outside it.
16 if ! [ -x /usr
/bin
/perl
]; then
17 # We are INSIDE the chroot
18 reporoot
=/@jailreporoot@
19 XDG_CONFIG_HOME
=/var
/empty
22 # We are NOT INSIDE the chroot
24 XDG_CONFIG_HOME
=@chroot@
/var
/empty
25 HOME
=@chroot@
/etc
/girocco
30 defined_ua
=@defined_git_server_ua@
32 export XDG_CONFIG_HOME
34 export GIT_CONFIG_NOSYSTEM
35 export GIT_ATTR_NOSYSTEM
36 export GIT_TERMINAL_PROMPT
39 if [ -n "$defined_ua" ]; then
44 # Only the following commands are allowed:
46 # git-shell -c "git-receive-pack 'dir'"
47 # git-shell -c "git receive-pack 'dir'"
48 # git-shell -c "git-upload-pack 'dir'"
49 # git-shell -c "git upload-pack 'dir'"
50 # git-shell -c "git-upload-archive 'dir'"
51 # git-shell -c "git upload-archive 'dir'"
53 # where dir must start with $reporoot/ but a leading/trailing '/' is optional
54 # as well as the final .git however if $dir does not start with $reporoot but
55 # adding a $reporoot prefix makes it work then the $reporoot prefix will be
58 if [ "$1" != "-c" ]; then
66 "git-receive-pack "*) type='receive-pack'; dir
="${dir#git-receive-pack }";;
67 "git receive-pack "*) type='receive-pack'; dir
="${dir#git receive-pack }";;
68 "git-upload-pack "*) type='upload-pack'; dir
="${dir#git-upload-pack }";;
69 "git upload-pack "*) type='upload-pack'; dir
="${dir#git upload-pack }";;
70 "git-upload-archive "*) type='upload-archive'; dir
="${dir#git-upload-archive }";;
71 "git upload-archive "*) type='upload-archive'; dir
="${dir#git upload-archive }";;
77 # valid project names only allow 0-9A-Za-z._+- plus the / separator and they
78 # are always single quoted so the only valid directory names will always start
79 # with a single quote and end with a single quote and not contain any internal
80 # character that needs to be escaped.
95 # Some shells do not properly handle quoting after # or % so we cannot
96 # put an explicit ' there in a way that works for all shells. Instead
97 # just remove a single character since we've already verified it's a '.
98 dir
="${dir#?}"; dir
="${dir%?}"
100 # add a missing leading /
107 # remove a trailing /
113 # add a missing trailing .git
123 # Allow it if prefixing with $reporoot matches an existing directory
124 if [ -d "$reporoot$dir" ]; then
132 # Valid project names never end in .git (we add that automagically), so a valid
133 # fork can never have .git at the end of any path component except the last.
134 # We check this to avoid a situation where a certain collection of pushed refs
135 # could be mistaken for a GIT_DIR. Git would ultimately complain, but some
136 # undesirable things could happen along the way.
138 # Remove the leading $reporoot and trailing .git to get a test string
139 testpath
="${dir#$reporoot/}"
140 testpath
="${testpath%.git}"
141 case "$testpath/" in *.
[Gg
][Ii
][Tt
]/*|_
*)
146 if ! [ -d "$dir" ] ||
! [ -f "$dir/HEAD" ] ||
! [ -d "$dir/objects" ]; then
151 proj
="${dir#$reporoot/}"; projbare
="${proj%.git}"
153 if [ "$type" = 'receive-pack' ] && ! [ -f "$dir/.nofetch" ]; then
154 echo "The $proj project is a mirror and may not be pushed to, sorry" >&2
158 if ! [ -x /usr
/bin
/perl
] && [ "$type" = 'receive-pack' ]; then
159 # We are INSIDE the chroot trying to push
161 if ! can_user_push
"$projbare"; then
162 # If mob is enabled and mob has push permissions and
163 # the current user is not the mob then it's a personal mob push
164 # presuming the special mob directory has been set up
165 if [ "$mob" = "mob" -a "$LOGNAME" != "mob" -a -d "$reporoot/$proj/mob" ] &&
166 can_user_push
"$projbare" mob
; then
169 > "/etc/sshactive/${LOGNAME},"
170 mv -f "/etc/sshactive/${LOGNAME}," "/etc/sshactive/${LOGNAME}"
172 exec git-shell
-c "git-receive-pack '$reporoot/$proj/mob'"
175 echo "The user '$LOGNAME' does not have push permissions for project '$proj'" >&2
176 echo "You may adjust push permissions at $webadmurl/editproj.cgi?name=$proj" >&2
181 > "/etc/sshactive/${LOGNAME},"
182 mv -f "/etc/sshactive/${LOGNAME}," "/etc/sshactive/${LOGNAME}"
186 exec git-shell
-c "git-$type '$dir'"