aboutsummaryrefslogtreecommitdiff
path: root/git/gitaclhook
diff options
context:
space:
mode:
Diffstat (limited to 'git/gitaclhook')
-rwxr-xr-xgit/gitaclhook169
1 files changed, 132 insertions, 37 deletions
diff --git a/git/gitaclhook b/git/gitaclhook
index f9b3d3a..dd31dd8 100755
--- a/git/gitaclhook
+++ b/git/gitaclhook
@@ -16,60 +16,116 @@
16 16
17use strict; 17use strict;
18use File::Spec; 18use File::Spec;
19use Pod::Man;
20use Pod::Usage;
19 21
20=doc 22=head1 NAME
21This hook is intended to be run as an "update" hook by git.
22It is called by git-receive-pack with arguments: refname old-sha1 new-sha1.
23 23
24If the hooks.aclfile keyword is defined in the repository's config file, 24gitaclhook - control access to git repositories
25
26=head1 SYNOPSIS
27
28B<gitaclhook> I<refname> I<old-sha1> I<new-sha1>
29
30B<gitaclhook --help>
31
32=head1 DESCRIPTION
33
34This program is intended to be run as an "update" hook by git.
35It is called by B<git-receive-pack> with arguments:
36I<refname> I<old-sha1> I<new-sha1>.
37
38If the B<hooks.aclfile> keyword is defined in the repository's config file,
25this hook will parse the file and allow or deny update depending on 39this hook will parse the file and allow or deny update depending on
26its settings. If hooks.aclfile is not defined, update is allowed 40its settings. If B<hooks.aclfile> is not defined, update is allowed
27unconditionally. 41unconditionally.
28 42
43=head1 ACL FILE
44
29The ACL file has the usual line-oriented syntax. Comments are introduced 45The ACL file has the usual line-oriented syntax. Comments are introduced
30by the # sign and extend to the end of the physical line. Comments and 46by the # sign and extend to the end of the physical line. Comments and
31empty lines are ignored. 47empty lines are ignored.
32 48
33Non-empty lines introduce ACL rules. The syntax is: 49Non-empty lines introduce ACL rules. The syntax is:
34 50
35 VERB PROJECT USER [OP REF] 51=over 4
52
53I<VERB> I<PROJECT> I<USER> [I<OP> I<REF>]
54
55=back
36 56
37where brackets denote optional parts. The parts of an ACL are: 57where brackets denote optional parts. The parts of an ACL are:
38 58
39VERB Either 'allow' or 'deny', to allow or deny the operation, 59=over 4
40 correspondingly. 60
61=item I<VERB>
62
63Either B<allow> or B<deny>, to allow or deny the operation, correspondingly.
64
65=item I<PROJECT>
41 66
42PROJECT The name of the project. It is obtained by removing the directory 67The name of the project. It is obtained by removing the directory
43and suffix parts of the repository pathname. Thus, if the repository 68and suffix parts of the repository pathname. Thus, if the repository
44 is located in /var/gitroot/foobar.git, then the corresponding name of 69is located in B</var/gitroot/foobar.git>, then the corresponding name of
45 the project is 'foobar'. 70the project is B<foobar>.
46 71
47USER Name of the user. The word 'all' stands for any user, the word 'none' 72An asterisk matches any project name.
73
74=item I<USER>
75
76Name of the user. The word B<all> stands for any user, the word B<none>
48matches no one at all. Otherwise, if this part begins with a percent 77matches no one at all. Otherwise, if this part begins with a percent
49 sign (%), the rest of characters aretreated as the name of the UNIX 78sign (B<%>), the rest of characters are treated as the name of the UNIX
50group to check and the rule matches any user in that group. Otherwise, 79group to check and the rule matches any user in that group. Otherwise,
51the literal match is assumed. 80the literal match is assumed.
52 81
82=back
83
53The optional parts are: 84The optional parts are:
54 85
55OP Requested operation codes. It is a string consisting of one or more 86=over 4
87
88=item I<OP>
89
90Requested operation codes. It is a string consisting of one or more
56of the following letters (case-insensitive): 91of the following letters (case-insensitive):
57 92
58 C: create new ref 93=over 8
59 D: delete existing ref 94
60 U: fast-forward existing ref (no commit loss) 95=item B<C>
61 R: rewind or rebase existing ref (commit loss) 96
97Create new ref.
98
99=item B<D>
100
101Delete existing ref.
102
103=item B<U>
104
105Fast-forward existing ref (no commit loss).
106
107=item B<R>
62 108
63REF Affected ref, relative to the git refs/ directory. If it begins with 109Rewind or rebase existing ref (commit loss).
64 a caret (^), it is treated as a Perl regular expression (with the ^ 110
65 being its part). If it ends with a /, it is treated as a prefix match, 111=back
66 so, e.g., "heads/baz/" matches "refs/heads/baz" and anything below. 112
113=item I<REF>
114
115Affected ref, relative to the git B<refs/> directory. If it begins with
116a caret (B<^>), it is treated as a Perl regular expression (with the B<^>
117being its part). If it ends with a B</>, it is treated as a prefix match,
118so, e.g., B<heads/baz/> matches B<refs/heads/baz> and anything below.
67Otherwise, it must match exactly the affected ref. 119Otherwise, it must match exactly the affected ref.
68 120
69The rule applies only if its PROJECT and USER parts match the project which is 121=back
70being updated and the user who requests the update, its OP contains the opcode 122
71of the requested operation and REF matches the affected ref. Missing REF 123=head1 RULE MATCHING
72and/or OP are treated as a match. 124
125The rule applies only if its I<PROJECT> and I<USER> parts match the project
126which is being updated and the user who requests the update, its I<OP>
127contains the opcode of the requested operation and I<REF> matches the affected
128ref. Missing I<REF> and/or I<OP> are treated as a match.
73 129
74If no rule applies, the operation is allowed. 130If no rule applies, the operation is allowed.
75 131
@@ -81,19 +137,49 @@ allow myprog %pm C ^heads/tags/v\\d+$
81 allow myprog admin CDUR 137 allow myprog admin CDUR
82 deny myprog all 138 deny myprog all
83 139
84Then the users from the 'devel' group will be able to push updates to 140Then the users from the B<devel> group will be able to push updates to
85refs/heads/master, the users from the 'pm' group will be allowed to do 141B<refs/heads/master>, the users from the B<pm> group will be allowed to do
86anything with refs under refs/heads and to create tags with names beginning 142anything with refs under B<refs/heads> and to create tags with names beginning
87with 'v' and containing only digits afterwards, and the user 'admin' will 143with B<v> and containing only digits afterwards, and the user B<admin> will
88be allowed to do anything he pleases. No other users will be allowed to 144be allowed to do anything he pleases. No other users will be allowed to
89update that repository. 145update that repository.
90 146
91Configuration settings: 147=head1 CONFIGURATION SETTINGS
148
149=over 4
150
151=item B<hooks.aclfile> STRING
152
153Name of the ACL file.
154
155=item B<hooks.acllog> STRING
156
157Send log info to this file.
158
159=item B<hooks.acldebug> BOOL
160
161Enable debugging.
92 162
93hooks.aclfile STRING Name of the ACL file 163=item B<hooks.aclquiet> BOOL
94hooks.acllog STRING Send log info to this file 164
95hooks.acldebug BOOL Enable debugging 165Suppress diagnostics on stderr.
96hooks.aclquiet BOOL Suppress diagnostics on stderr 166
167=item B<hooks.httpd-user> STRING
168
169Name of the user httpd runs as. Define it if the repository can be
170accessed via HTTP(S). If B<gitaclhook> is run as this user, it will
171get the name of the user on behalf of which the update is performed
172from the environment variable B<REMOTE_USER>.
173
174=back
175
176=head1 SEE ALSO
177
178B<git-receive-pack>(1).
179
180=head1 AUTHOR
181
182Sergey Poznyakoff, <gray@gno.org>
97 183
98=cut 184=cut
99 185
@@ -217,7 +303,7 @@ sub check_acl($$$) {
217 deny("malformed line", "$filename:$line") 303 deny("malformed line", "$filename:$line")
218 unless $#x >= 2; 304 unless $#x >= 2;
219 305
220 next if ($x[1] ne $project); 306 next if ($x[1] ne "*" and $x[1] ne $project);
221 next unless match_user($x[2]); 307 next unless match_user($x[2]);
222 next if ($#x >= 3 && index(uc $x[3], $op) == -1); 308 next if ($#x >= 3 && index(uc $x[3], $op) == -1);
223 next if ($#x == 4 && !match_ref($x[4])); 309 next if ($#x == 4 && !match_ref($x[4]));
@@ -233,7 +319,10 @@ sub check_acl($$$) {
233#### 319####
234 320
235# Sanity checks 321# Sanity checks
236deny "don't run this script from the command line" unless ($git_dir); 322unless ($git_dir) {
323 pod2usage(-exitstatus => 0, -verbose => 2) if ($ref eq "--help");
324 deny "try \"$0 --help\" for fore info"
325}
237 326
238$debug = git_value('config', '--bool', 'hooks.acldebug') unless ($debug); 327$debug = git_value('config', '--bool', 'hooks.acldebug') unless ($debug);
239$logfile = git_value('config', 'hooks.acllog'); 328$logfile = git_value('config', 'hooks.acllog');
@@ -242,6 +331,12 @@ if ($logfile && $logfile !~ /[>|]/) {
242} 331}
243$quiet = git_value('config', 'hooks.aclquiet') unless ($debug); 332$quiet = git_value('config', 'hooks.aclquiet') unless ($debug);
244 333
334my $httpdusr = git_value('config', 'hooks.httpd-user');
335if (defined($httpdusr) and $user_name eq $httpdusr) {
336 deny "need authenticated user" unless defined($ENV{AUTH_TYPE});