##// END OF EJS Templates
acl: support for group definitions in section [acl.groups], which take precedence over OS-level groups
Elifarley Callado Coelho Cruz -
r11114:62714143 default
parent child Browse files
Show More
@@ -1,232 +1,240
1 # acl.py - changeset access control for mercurial
1 # acl.py - changeset access control for mercurial
2 #
2 #
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 '''hooks for controlling repository access
8 '''hooks for controlling repository access
9
9
10 This hook makes it possible to allow or deny write access to given
10 This hook makes it possible to allow or deny write access to given
11 branches and paths of a repository when receiving incoming changesets
11 branches and paths of a repository when receiving incoming changesets
12 via pretxnchangegroup and pretxncommit.
12 via pretxnchangegroup and pretxncommit.
13
13
14 The authorization is matched based on the local user name on the
14 The authorization is matched based on the local user name on the
15 system where the hook runs, and not the committer of the original
15 system where the hook runs, and not the committer of the original
16 changeset (since the latter is merely informative).
16 changeset (since the latter is merely informative).
17
17
18 The acl hook is best used along with a restricted shell like hgsh,
18 The acl hook is best used along with a restricted shell like hgsh,
19 preventing authenticating users from doing anything other than pushing
19 preventing authenticating users from doing anything other than pushing
20 or pulling. The hook is not safe to use if users have interactive
20 or pulling. The hook is not safe to use if users have interactive
21 shell access, as they can then disable the hook. Nor is it safe if
21 shell access, as they can then disable the hook. Nor is it safe if
22 remote users share an account, because then there is no way to
22 remote users share an account, because then there is no way to
23 distinguish them.
23 distinguish them.
24
24
25 The order in which access checks are performed is:
25 The order in which access checks are performed is:
26
26
27 1) Deny list for branches (section ``acl.deny.branches``)
27 1) Deny list for branches (section ``acl.deny.branches``)
28 2) Allow list for branches (section ``acl.allow.branches``)
28 2) Allow list for branches (section ``acl.allow.branches``)
29 3) Deny list for paths (section ``acl.deny``)
29 3) Deny list for paths (section ``acl.deny``)
30 4) Allow list for paths (section ``acl.allow``)
30 4) Allow list for paths (section ``acl.allow``)
31
31
32 The allow and deny sections take key-value pairs.
32 The allow and deny sections take key-value pairs.
33
33
34 Branch-based Access Control
34 Branch-based Access Control
35 ---------------------------
35 ---------------------------
36
36
37 Use the ``acl.deny.branches`` and ``acl.allow.branches`` sections to
37 Use the ``acl.deny.branches`` and ``acl.allow.branches`` sections to
38 have branch-based access control. Keys in these sections can be
38 have branch-based access control. Keys in these sections can be
39 either:
39 either:
40
40
41 - a branch name, or
41 - a branch name, or
42 - an asterisk, to match any branch;
42 - an asterisk, to match any branch;
43
43
44 The corresponding values can be either:
44 The corresponding values can be either:
45
45
46 - a comma-separated list containing users and groups, or
46 - a comma-separated list containing users and groups, or
47 - an asterisk, to match anyone;
47 - an asterisk, to match anyone;
48
48
49 Path-based Access Control
49 Path-based Access Control
50 -------------------------
50 -------------------------
51
51
52 Use the ``acl.deny`` and ``acl.allow`` sections to have path-based
52 Use the ``acl.deny`` and ``acl.allow`` sections to have path-based
53 access control. Keys in these sections accept a subtree pattern (with
53 access control. Keys in these sections accept a subtree pattern (with
54 a glob syntax by default). The corresponding values follow the same
54 a glob syntax by default). The corresponding values follow the same
55 syntax as the other sections above.
55 syntax as the other sections above.
56
56
57 Groups
57 Groups
58 ------
58 ------
59
59
60 Group names must be prefixed with an ``@`` symbol. Specifying a group
60 Group names must be prefixed with an ``@`` symbol. Specifying a group
61 name has the same effect as specifying all the users in that group.
61 name has the same effect as specifying all the users in that group.
62
62
63 Example Configuration
63 Example Configuration
64 ---------------------
64 ---------------------
65
65
66 ::
66 ::
67
67
68 [hooks]
68 [hooks]
69
69
70 # Use this if you want to check access restrictions at commit time
70 # Use this if you want to check access restrictions at commit time
71 pretxncommit.acl = python:hgext.acl.hook
71 pretxncommit.acl = python:hgext.acl.hook
72
72
73 # Use this if you want to check access restrictions for pull, push,
73 # Use this if you want to check access restrictions for pull, push,
74 # bundle and serve.
74 # bundle and serve.
75 pretxnchangegroup.acl = python:hgext.acl.hook
75 pretxnchangegroup.acl = python:hgext.acl.hook
76
76
77 [acl]
77 [acl]
78 # Check whether the source of incoming changes is in this list where
78 # Check whether the source of incoming changes is in this list where
79 # "serve" == ssh or http, and "push", "pull" and "bundle" are the
79 # "serve" == ssh or http, and "push", "pull" and "bundle" are the
80 # corresponding hg commands.
80 # corresponding hg commands.
81 sources = serve
81 sources = serve
82
82
83 [acl.deny.branches]
83 [acl.deny.branches]
84
84
85 # Everyone is denied to the frozen branch:
85 # Everyone is denied to the frozen branch:
86 frozen-branch = *
86 frozen-branch = *
87
87
88 # A bad user is denied on all branches:
88 # A bad user is denied on all branches:
89 * = bad-user
89 * = bad-user
90
90
91 [acl.allow.branches]
91 [acl.allow.branches]
92
92
93 # A few users are allowed on branch-a:
93 # A few users are allowed on branch-a:
94 branch-a = user-1, user-2, user-3
94 branch-a = user-1, user-2, user-3
95
95
96 # Only one user is allowed on branch-b:
96 # Only one user is allowed on branch-b:
97 branch-b = user-1
97 branch-b = user-1
98
98
99 # The super user is allowed on any branch:
99 # The super user is allowed on any branch:
100 * = super-user
100 * = super-user
101
101
102 # Everyone is allowed on branch-for-tests:
102 # Everyone is allowed on branch-for-tests:
103 branch-for-tests = *
103 branch-for-tests = *
104
104
105 [acl.deny]
105 [acl.deny]
106 # This list is checked first. If a match is found, acl.allow is not
106 # This list is checked first. If a match is found, acl.allow is not
107 # checked. All users are granted access if acl.deny is not present.
107 # checked. All users are granted access if acl.deny is not present.
108 # Format for both lists: glob pattern = user, ..., @group, ...
108 # Format for both lists: glob pattern = user, ..., @group, ...
109
109
110 # To match everyone, use an asterisk for the user:
110 # To match everyone, use an asterisk for the user:
111 # my/glob/pattern = *
111 # my/glob/pattern = *
112
112
113 # user6 will not have write access to any file:
113 # user6 will not have write access to any file:
114 ** = user6
114 ** = user6
115
115
116 # Group "hg-denied" will not have write access to any file:
116 # Group "hg-denied" will not have write access to any file:
117 ** = @hg-denied
117 ** = @hg-denied
118
118
119 # Nobody will be able to change "DONT-TOUCH-THIS.txt", despite
119 # Nobody will be able to change "DONT-TOUCH-THIS.txt", despite
120 # everyone being able to change all other files. See below.
120 # everyone being able to change all other files. See below.
121 src/main/resources/DONT-TOUCH-THIS.txt = *
121 src/main/resources/DONT-TOUCH-THIS.txt = *
122
122
123 [acl.allow]
123 [acl.allow]
124 # if acl.allow not present, all users allowed by default
124 # if acl.allow not present, all users allowed by default
125 # empty acl.allow = no users allowed
125 # empty acl.allow = no users allowed
126
126
127 # User "doc_writer" has write access to any file under the "docs"
127 # User "doc_writer" has write access to any file under the "docs"
128 # folder:
128 # folder:
129 docs/** = doc_writer
129 docs/** = doc_writer
130
130
131 # User "jack" and group "designers" have write access to any file
131 # User "jack" and group "designers" have write access to any file
132 # under the "images" folder:
132 # under the "images" folder:
133 images/** = jack, @designers
133 images/** = jack, @designers
134
134
135 # Everyone (except for "user6" - see acl.deny above) will have write
135 # Everyone (except for "user6" - see acl.deny above) will have write
136 # access to any file under the "resources" folder (except for 1
136 # access to any file under the "resources" folder (except for 1
137 # file. See acl.deny):
137 # file. See acl.deny):
138 src/main/resources/** = *
138 src/main/resources/** = *
139
139
140 .hgtags = release_engineer
140 .hgtags = release_engineer
141
141
142 '''
142 '''
143
143
144 from mercurial.i18n import _
144 from mercurial.i18n import _
145 from mercurial import util, match
145 from mercurial import util, match
146 import getpass, urllib, grp
146 import getpass, urllib, grp
147
147
148 def _getusers(group):
148 def _getusers(ui, group):
149
150 # First, try to use group definition from section [acl.groups]
151 hgrcusers = ui.configlist('acl.groups', group)
152 if hgrcusers:
153 return hgrcusers
154
155 ui.debug('acl: "%s" not defined in [acl.groups]\n' % group)
156 # If no users found in group definition, get users from OS-level group
149 return grp.getgrnam(group).gr_mem
157 return grp.getgrnam(group).gr_mem
150
158
151 def _usermatch(user, usersorgroups):
159 def _usermatch(ui, user, usersorgroups):
152
160
153 if usersorgroups == '*':
161 if usersorgroups == '*':
154 return True
162 return True
155
163
156 for ug in usersorgroups.replace(',', ' ').split():
164 for ug in usersorgroups.replace(',', ' ').split():
157 if user == ug or ug.find('@') == 0 and user in _getusers(ug[1:]):
165 if user == ug or ug.find('@') == 0 and user in _getusers(ui, ug[1:]):
158 return True
166 return True
159
167
160 return False
168 return False
161
169
162 def buildmatch(ui, repo, user, key):
170 def buildmatch(ui, repo, user, key):
163 '''return tuple of (match function, list enabled).'''
171 '''return tuple of (match function, list enabled).'''
164 if not ui.has_section(key):
172 if not ui.has_section(key):
165 ui.debug('acl: %s not enabled\n' % key)
173 ui.debug('acl: %s not enabled\n' % key)
166 return None
174 return None
167
175
168 pats = [pat for pat, users in ui.configitems(key)
176 pats = [pat for pat, users in ui.configitems(key)
169 if _usermatch(user, users)]
177 if _usermatch(ui, user, users)]
170 ui.debug('acl: %s enabled, %d entries for user %s\n' %
178 ui.debug('acl: %s enabled, %d entries for user %s\n' %
171 (key, len(pats), user))
179 (key, len(pats), user))
172
180
173 if not repo:
181 if not repo:
174 if pats:
182 if pats:
175 return lambda b: '*' in pats or b in pats
183 return lambda b: '*' in pats or b in pats
176 return lambda b: False
184 return lambda b: False
177
185
178 if pats:
186 if pats:
179 return match.match(repo.root, '', pats)
187 return match.match(repo.root, '', pats)
180 return match.exact(repo.root, '', [])
188 return match.exact(repo.root, '', [])
181
189
182
190
183 def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
191 def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
184 if hooktype not in ['pretxnchangegroup', 'pretxncommit']:
192 if hooktype not in ['pretxnchangegroup', 'pretxncommit']:
185 raise util.Abort(_('config error - hook type "%s" cannot stop '
193 raise util.Abort(_('config error - hook type "%s" cannot stop '
186 'incoming changesets nor commits') % hooktype)
194 'incoming changesets nor commits') % hooktype)
187 if (hooktype == 'pretxnchangegroup' and
195 if (hooktype == 'pretxnchangegroup' and
188 source not in ui.config('acl', 'sources', 'serve').split()):
196 source not in ui.config('acl', 'sources', 'serve').split()):
189 ui.debug('acl: changes have source "%s" - skipping\n' % source)
197 ui.debug('acl: changes have source "%s" - skipping\n' % source)
190 return
198 return
191
199
192 user = None
200 user = None
193 if source == 'serve' and 'url' in kwargs:
201 if source == 'serve' and 'url' in kwargs:
194 url = kwargs['url'].split(':')
202 url = kwargs['url'].split(':')
195 if url[0] == 'remote' and url[1].startswith('http'):
203 if url[0] == 'remote' and url[1].startswith('http'):
196 user = urllib.unquote(url[3])
204 user = urllib.unquote(url[3])
197
205
198 if user is None:
206 if user is None:
199 user = getpass.getuser()
207 user = getpass.getuser()
200
208
201 cfg = ui.config('acl', 'config')
209 cfg = ui.config('acl', 'config')
202 if cfg:
210 if cfg:
203 ui.readconfig(cfg, sections = ['acl.allow.branches',
211 ui.readconfig(cfg, sections = ['acl.groups', 'acl.allow.branches',
204 'acl.deny.branches', 'acl.allow', 'acl.deny'])
212 'acl.deny.branches', 'acl.allow', 'acl.deny'])
205
213
206 allowbranches = buildmatch(ui, None, user, 'acl.allow.branches')
214 allowbranches = buildmatch(ui, None, user, 'acl.allow.branches')
207 denybranches = buildmatch(ui, None, user, 'acl.deny.branches')
215 denybranches = buildmatch(ui, None, user, 'acl.deny.branches')
208 allow = buildmatch(ui, repo, user, 'acl.allow')
216 allow = buildmatch(ui, repo, user, 'acl.allow')
209 deny = buildmatch(ui, repo, user, 'acl.deny')
217 deny = buildmatch(ui, repo, user, 'acl.deny')
210
218
211 for rev in xrange(repo[node], len(repo)):
219 for rev in xrange(repo[node], len(repo)):
212 ctx = repo[rev]
220 ctx = repo[rev]
213 branch = ctx.branch()
221 branch = ctx.branch()
214 if denybranches and denybranches(branch):
222 if denybranches and denybranches(branch):
215 raise util.Abort(_('acl: user "%s" denied on branch "%s"'
223 raise util.Abort(_('acl: user "%s" denied on branch "%s"'
216 ' (changeset "%s")')
224 ' (changeset "%s")')
217 % (user, branch, ctx))
225 % (user, branch, ctx))
218 if allowbranches and not allowbranches(branch):
226 if allowbranches and not allowbranches(branch):
219 raise util.Abort(_('acl: user "%s" not allowed on branch "%s"'
227 raise util.Abort(_('acl: user "%s" not allowed on branch "%s"'
220 ' (changeset "%s")')
228 ' (changeset "%s")')
221 % (user, branch, ctx))
229 % (user, branch, ctx))
222 ui.debug('acl: branch access granted: "%s" on branch "%s"\n'
230 ui.debug('acl: branch access granted: "%s" on branch "%s"\n'
223 % (ctx, branch))
231 % (ctx, branch))
224
232
225 for f in ctx.files():
233 for f in ctx.files():
226 if deny and deny(f):
234 if deny and deny(f):
227 ui.debug('acl: user %s denied on %s\n' % (user, f))
235 ui.debug('acl: user %s denied on %s\n' % (user, f))
228 raise util.Abort(_('acl: access denied for changeset %s') % ctx)
236 raise util.Abort(_('acl: access denied for changeset %s') % ctx)
229 if allow and not allow(f):
237 if allow and not allow(f):
230 ui.debug('acl: user %s not allowed on %s\n' % (user, f))
238 ui.debug('acl: user %s not allowed on %s\n' % (user, f))
231 raise util.Abort(_('acl: access denied for changeset %s') % ctx)
239 raise util.Abort(_('acl: access denied for changeset %s') % ctx)
232 ui.debug('acl: allowing changeset %s\n' % ctx)
240 ui.debug('acl: allowing changeset %s\n' % ctx)
@@ -1,162 +1,168
1 #!/bin/sh
1 #!/bin/sh
2
2
3 do_push()
3 do_push()
4 {
4 {
5 user=$1
5 user=$1
6 shift
6 shift
7
7
8 echo "Pushing as user $user"
8 echo "Pushing as user $user"
9 echo 'hgrc = """'
9 echo 'hgrc = """'
10 sed -e 1,2d b/.hg/hgrc | grep -v "$HGTMP"
10 sed -e 1,2d b/.hg/hgrc | grep -v "$HGTMP"
11 echo '"""'
11 echo '"""'
12 if test -f acl.config; then
12 if test -f acl.config; then
13 echo 'acl.config = """'
13 echo 'acl.config = """'
14 cat acl.config
14 cat acl.config
15 echo '"""'
15 echo '"""'
16 fi
16 fi
17 # On AIX /etc/profile sets LOGNAME read-only. So
17 # On AIX /etc/profile sets LOGNAME read-only. So
18 # LOGNAME=$user hg --cws a --debug push ../b
18 # LOGNAME=$user hg --cws a --debug push ../b
19 # fails with "This variable is read only."
19 # fails with "This variable is read only."
20 # Use env to work around this.
20 # Use env to work around this.
21 env LOGNAME=$user hg --cwd a --debug push ../b
21 env LOGNAME=$user hg --cwd a --debug push ../b
22 hg --cwd b rollback
22 hg --cwd b rollback
23 hg --cwd b --quiet tip
23 hg --cwd b --quiet tip
24 echo
24 echo
25 }
25 }
26
26
27 init_config()
27 init_config()
28 {
28 {
29 cat > fakegroups.py <<EOF
29 cat > fakegroups.py <<EOF
30 from hgext import acl
30 from hgext import acl
31 acl._getusers = lambda x: ["fred", "betty"]
31 def fakegetusers(ui, group):
32 try:
33 return acl._getusersorig(ui, group)
34 except:
35 return ["fred", "betty"]
36 acl._getusersorig = acl._getusers
37 acl._getusers = fakegetusers
32 EOF
38 EOF
33
39
34 rm -f acl.config
40 rm -f acl.config
35 cat > $config <<EOF
41 cat > $config <<EOF
36 [hooks]
42 [hooks]
37 pretxnchangegroup.acl = python:hgext.acl.hook
43 pretxnchangegroup.acl = python:hgext.acl.hook
38 [acl]
44 [acl]
39 sources = push
45 sources = push
40 [extensions]
46 [extensions]
41 f=$PWD/fakegroups.py
47 f=$PWD/fakegroups.py
42 EOF
48 EOF
43 }
49 }
44
50
45 hg init a
51 hg init a
46 cd a
52 cd a
47 mkdir foo foo/Bar quux
53 mkdir foo foo/Bar quux
48 echo 'in foo' > foo/file.txt
54 echo 'in foo' > foo/file.txt
49 echo 'in foo/Bar' > foo/Bar/file.txt
55 echo 'in foo/Bar' > foo/Bar/file.txt
50 echo 'in quux' > quux/file.py
56 echo 'in quux' > quux/file.py
51 hg add -q
57 hg add -q
52 hg ci -m 'add files' -d '1000000 0'
58 hg ci -m 'add files' -d '1000000 0'
53 echo >> foo/file.txt
59 echo >> foo/file.txt
54 hg ci -m 'change foo/file' -d '1000001 0'
60 hg ci -m 'change foo/file' -d '1000001 0'
55 echo >> foo/Bar/file.txt
61 echo >> foo/Bar/file.txt
56 hg ci -m 'change foo/Bar/file' -d '1000002 0'
62 hg ci -m 'change foo/Bar/file' -d '1000002 0'
57 echo >> quux/file.py
63 echo >> quux/file.py
58 hg ci -m 'change quux/file' -d '1000003 0'
64 hg ci -m 'change quux/file' -d '1000003 0'
59 hg tip --quiet
65 hg tip --quiet
60
66
61 cd ..
67 cd ..
62 hg clone -r 0 a b
68 hg clone -r 0 a b
63
69
64 echo '[extensions]' >> $HGRCPATH
70 echo '[extensions]' >> $HGRCPATH
65 echo 'acl =' >> $HGRCPATH
71 echo 'acl =' >> $HGRCPATH
66
72
67 config=b/.hg/hgrc
73 config=b/.hg/hgrc
68
74
69 echo
75 echo
70
76
71 echo 'Extension disabled for lack of a hook'
77 echo 'Extension disabled for lack of a hook'
72 do_push fred
78 do_push fred
73
79
74 echo '[hooks]' >> $config
80 echo '[hooks]' >> $config
75 echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
81 echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
76
82
77 echo 'Extension disabled for lack of acl.sources'
83 echo 'Extension disabled for lack of acl.sources'
78 do_push fred
84 do_push fred
79
85
80 echo 'No [acl.allow]/[acl.deny]'
86 echo 'No [acl.allow]/[acl.deny]'
81 echo '[acl]' >> $config
87 echo '[acl]' >> $config
82 echo 'sources = push' >> $config
88 echo 'sources = push' >> $config
83 do_push fred
89 do_push fred
84
90
85 echo 'Empty [acl.allow]'
91 echo 'Empty [acl.allow]'
86 echo '[acl.allow]' >> $config
92 echo '[acl.allow]' >> $config
87 do_push fred
93 do_push fred
88
94
89 echo 'fred is allowed inside foo/'
95 echo 'fred is allowed inside foo/'
90 echo 'foo/** = fred' >> $config
96 echo 'foo/** = fred' >> $config
91 do_push fred
97 do_push fred
92
98
93 echo 'Empty [acl.deny]'
99 echo 'Empty [acl.deny]'
94 echo '[acl.deny]' >> $config
100 echo '[acl.deny]' >> $config
95 do_push barney
101 do_push barney
96
102
97 echo 'fred is allowed inside foo/, but not foo/bar/ (case matters)'
103 echo 'fred is allowed inside foo/, but not foo/bar/ (case matters)'
98 echo 'foo/bar/** = fred' >> $config
104 echo 'foo/bar/** = fred' >> $config
99 do_push fred
105 do_push fred
100
106
101 echo 'fred is allowed inside foo/, but not foo/Bar/'
107 echo 'fred is allowed inside foo/, but not foo/Bar/'
102 echo 'foo/Bar/** = fred' >> $config
108 echo 'foo/Bar/** = fred' >> $config
103 do_push fred
109 do_push fred
104
110
105 echo 'barney is not mentioned => not allowed anywhere'
111 echo 'barney is not mentioned => not allowed anywhere'
106 do_push barney
112 do_push barney
107
113
108 echo 'barney is allowed everywhere'
114 echo 'barney is allowed everywhere'
109 echo '[acl.allow]' >> $config
115 echo '[acl.allow]' >> $config
110 echo '** = barney' >> $config
116 echo '** = barney' >> $config
111 do_push barney
117 do_push barney
112
118
113 echo 'wilma can change files with a .txt extension'
119 echo 'wilma can change files with a .txt extension'
114 echo '**/*.txt = wilma' >> $config
120 echo '**/*.txt = wilma' >> $config
115 do_push wilma
121 do_push wilma
116
122
117 echo 'file specified by acl.config does not exist'
123 echo 'file specified by acl.config does not exist'
118 echo '[acl]' >> $config
124 echo '[acl]' >> $config
119 echo 'config = ../acl.config' >> $config
125 echo 'config = ../acl.config' >> $config
120 do_push barney
126 do_push barney
121
127
122 echo 'betty is allowed inside foo/ by a acl.config file'
128 echo 'betty is allowed inside foo/ by a acl.config file'
123 echo '[acl.allow]' >> acl.config
129 echo '[acl.allow]' >> acl.config
124 echo 'foo/** = betty' >> acl.config
130 echo 'foo/** = betty' >> acl.config
125 do_push betty
131 do_push betty
126
132
127 echo 'acl.config can set only [acl.allow]/[acl.deny]'
133 echo 'acl.config can set only [acl.allow]/[acl.deny]'
128 echo '[hooks]' >> acl.config
134 echo '[hooks]' >> acl.config
129 echo 'changegroup.acl = false' >> acl.config
135 echo 'changegroup.acl = false' >> acl.config
130 do_push barney
136 do_push barney
131
137
132 # asterisk
138 # asterisk
133
139
134 init_config
140 init_config
135
141
136 echo 'asterisk test'
142 echo 'asterisk test'
137 echo '[acl.allow]' >> $config
143 echo '[acl.allow]' >> $config
138 echo "** = fred" >> $config
144 echo "** = fred" >> $config
139 echo "fred is always allowed"
145 echo "fred is always allowed"
140 do_push fred
146 do_push fred
141
147
142 echo '[acl.deny]' >> $config
148 echo '[acl.deny]' >> $config
143 echo "foo/Bar/** = *" >> $config
149 echo "foo/Bar/** = *" >> $config
144 echo "no one is allowed inside foo/Bar/"
150 echo "no one is allowed inside foo/Bar/"
145 do_push fred
151 do_push fred
146
152
147 # Groups
153 # Groups
148
154
149 init_config
155 init_config
150
156
151 echo 'OS-level groups'
157 echo 'OS-level groups'
152 echo '[acl.allow]' >> $config
158 echo '[acl.allow]' >> $config
153 echo "** = @group1" >> $config
159 echo "** = @group1" >> $config
154 echo "@group1 is always allowed"
160 echo "@group1 is always allowed"
155 do_push fred
161 do_push fred
156
162
157 echo '[acl.deny]' >> $config
163 echo '[acl.deny]' >> $config
158 echo "foo/Bar/** = @group1" >> $config
164 echo "foo/Bar/** = @group1" >> $config
159 echo "@group is allowed inside anything but foo/Bar/"
165 echo "@group is allowed inside anything but foo/Bar/"
160 do_push fred
166 do_push fred
161
167
162
168
General Comments 0
You need to be logged in to leave comments. Login now