This commit series refactors all the rights querying logic.
- old repo_rights sub renamed to wild_repo_rights
- new repo_rights sub to be a single entry point for most rights
queries
- callable from gl-auth-command and expand_wild
- callable from *outside* too, as long as $ENV{GL_USER} is set
- the format of the returned permissions contains C, R, and W as
applicable, with sigils reflecting the 3 possible ways in which you
can get R or W perms (2 ways for C):
@R means @all users have the same access
#R means you're a "super user" (think root's shell prompt) so
you can see all repos
R is the normal, explicit, access
Always passing "-p 22" to ssh (or "-P 22" to scp) if no custom port is given on
the command line causes trouble when not using a host name but an SSH session
name (as defined in .ssh/config) which defines a non-standard port, because the
port given on the command line overrides that port.
Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
Having to specify "D" separately from RW or RW+ was cumbersome, and
although I don't actually use this feature, I can see the point.
One way to think of this is:
- RW and RW+ were the only existing branch level rights
- it doesnt make sense to have D rights without W (hence RW) rights
- so we simply suffix a D to these if required.
Thus you can have RW, RW+, RWD, RW+D.
I hope the (hopefully few) of you who have started to use this feature
will convert your configs when you next upgrade to "pu".
I now regret pushing the previous syntax to master too quickly -- lots
of people use master only, and on the next promotion of pu the syntax
will change. To reduce this exposure, this change will be promoted to
master very soon.
Previous implementations of "give shell access to some gitolite users"
feature were crap. There was no easy/elegant way to ensure that someone
who had repo admin access would not manage to get himself shell access.
Giving someone shell access requires that you should have shell access
in the first place, so the simplest way is to enable it from the server
side only.
So now that we decided to do that, we may as well prepare for other,
future, commands by starting a server-side utility program with
sub-commands (the only current one being "shell-add")
normally, RW+ means permission to rewind or delete.
Now, if you use "D" permission anywhere in a repo config, that means
"delete" and RW+ then means only "rewind", no delete.
All this is about a user trying to look if a repo exists or not, when he
does not have any access to that repo. Ideally, "repo does not exist"
should be indistinguishable from "you dont have perms to that repo".
(1) if $GL_WILDREPOS is not set, you either get a permissions error, or
a "$repo not found in compiled config" death. Fixed.
(2) if $GL_WILDREPOS is set, you either get either a permissions error,
or a "$repo has no matches" death. Fixed.
(3) The following combination leaks info about repo existence:
- actual repo doesn't exist
- spying user don't have C perms
- repo patt doesn't contain CREATER
- RW+ = CREATER is specified (as is normal)
In such case, the "convenience copy" of the ACL that parse_acl
makes, coupled with substituting CREATER for the invoking user means
$repos{$actual_repo} has RW+ for the spying user. This means the
access denied doesn't happen, and control passes to git, which
promptly expresses it unhappiness and angst over being given a repo
that 'does not appear to be a git repository'
This doesn't happen if all those conditions are not met:
- if repo exists, CREATER is set to the real creater, so RW+ =
CREATER does not gain spying user anything
- if spying user has C perms it just gets created, because he has
rights. This is also info leak but we can't prevent it; tighten
the config (maybe by including CREATER in repo pattern) if this
is not wanted
- if repo patt contains CREATER it will never match someone else's
repo anyway!
a configuration like this:
repo CREATER/.*
C = CREATER
RW+ = WRITERS
was buggy; CREATER was implicitly part of WRITERS so he got RW
permissions implicitly, so the push went through
what this means is that until now, everyone who used easy-install
(without needing to set $GIT_PATH in the rc file) had a client-side PATH
that was perfectly valid on the server side also!
- no need to put it at the end of the config file now, yeaaay!
- @all for @all is meaningless and not supported. People asking will
be told to get a life or use git-daemon.
- NAME/ limits for @all repos is ignored for efficiency reasons.
Data dumper was failing (returning an empty string!) on an input config
file of about 350 lines or so (output 2400 lines or so).
Removing the sort sub fixed the problem.
To recap why that sub was put in (see deleted lines in this commit for
details), what we really want is that $creater must appear *last* in the
resulting dump.
So we trick it. "man ascii" tells you that ~ is the highest valued
ASCII character (yes, I know, not utf-8 safe etc... I'll deal with that
if and when needed or punt!). So we just put that in front of $creater
and remove it later...
You *don't* want to do this for $readers and $writers -- then they will
once again sort *after* $creater, which would be a bad thing. Also,
it's probably better this way, because now the order of the hash keys
will be: $readers, $writers, any actual users listed, and then $creater.
This means the effective access rights will be:
1. if you are the creater you get CREATER's rights
2. else if your userid is listed *explicitly* in the config, you get
those rights
3. else if you've been setperm'd as a writer, you get WRITERS rights
4. else if you've been setperm'd as a reader, you get READERS rights
This is different from what used to happen till now; READERS and WRITERS
used to trump explicitly given rights. I'd been meaning to fix that
somehow, but never got around to it, until this DDD (damn Data Dumper!)
forced my hand :)
The new style personal branches work by interpreting the special
sequence /USER/ (including the slashes) in a refname. Docs should be in
the next commit...
the changes to cp/scp are because without "-p" they dont carry perms
across to existing files. So if you forgot to chmod +x your custom
hook and ran easy install, then after that you have to go to the server
side to fix the perms...
I've been unwilling to create the authkeys file if it does not already
exist, because it represents a significant change in accessibility for
that account.
However, in the "distro package" scenario, one wants to make it as easy
as possible for the end-user (who is actually an admin for the gitolite
being hosted on his account, let's not forget) to use.
And it seems that in some cases that might mean he does not (yet) have a
~/.ssh even...
when repos are copied over from elsewhere, one had to run easy install
once again to make the new (OS-copied) repo contain the proper update
hook.
We eliminate this step now, using a new, empty, "hook" as a sentinel and
having "compile" check/fix all repos' hooks.
Since you have to add the repos to conf anyway, this makes it as
seamless as possible. The correct sequence now is
- (server) copy the repo at the OS level
- (admin clone) add it to conf/gitolite.conf, commit, push
Currently the pattern of expand command is line anchored. This is
different than in e.g. grep, and causes extra work to add '.*' prefix
and/or suffix in many use cases.
The new semantics now mean you might get more matches than you would
have gotten earlier. However, the expand command is still totally
undocumented, so I think it is acceptable to change the functionality.
;)
This patch removes the anchoring. So for earlier behavior the specified
pattern needs be in form of '^<pattern>$'. The default pattern is also
changed from '.*' to '^', so there might be even a small speed
improvement. =)
Signed-off-by: Teemu Matilainen <teemu.matilainen@reaktor.fi>
stupid me; committed the easy install patch on master *and* pushed,
instead of on pu...
Since I dont want to rewind master, we end up with this completely
unnecessary merge.
let expand_list be just that "expand a list", and leave checking to be
done outside.
otherwise, commit 690604d79 has the side effect of restricting refs to
$REPOPATT_PATT, and so for instance barfing on the perfectly valid
RW+ refs/(?!heads/master) = alice bob
(thanks to Teemu for catching this)
[TODO: allow a callback for a password checking function, such as
"passwd_policy_check". Question is where the function would go.
~/.gitolite.rc is the only possible place among the current set of files
but I'd rather leave that as a list of simple name=value lines for all
sorts of reasons. So maybe something like ~/.gitolite.pm (analogous to
the "gitolite.pm" in the sources I supply), which would get "require'd"
if found, and would contain all user-defined functions like this one...
needs some thinking about]
this came up in some other discussion with bremner. As usual I said no
I won't do it because I don't see any real need.
...then I realised it's just one line :)
(about this commit)
The install doc now describes both the ways of installing gitolite.
It also has a handy appendix for package maintainers describing what
they need to do.
(about the "dps" -- distro packaging support -- commit series)
This commit is the last in the chain meant to make gitolite more
friendly for package maintainers.
Frankly, I never really thought gitolite would get big enough or
important enough for someone to package it, and I always did just
the bare minimum I needed to get it working, first for myself, then
anyone who hopped onto #git and asked. As a result, it had some
quirks in terms of what is expected where and so on...
Luckily, it didn't take a lot of changes to fix it, and this series
of commits should help make it very easy to package gitolite for
system-wide use.
The old install method will now use conf/VERSION instead of src/VERSION everywhere.
The new one, if you use the builtin make file to "make branch.tar" will also create just such a file
gl-install copies
- the initial rc file to ~/.gitolite.rc if it doesn't exist
- src and hooks to GL_ADMINDIR
Make it aware of a package-based setup sequence, where the above two
change somewhat; see code diff.
This should be the last bit of change needed to prepare gitolite setup
so that a distro package maintainer does not have to fiddle too much
with code inside.
(What remains is docs, and a setup script for server-side use, to
replace the latter part of easy install)
if you have read access to the admin repo, you can say
ssh git@server info user1 [...]
Original idea and code by Karteek E. The motivation is to quickly and
easily check what perms a user has. Technically nothing that you can't
glean from the config file itself but it serves as a double check or a
mild debugging aid perhaps.
However note that the branch level rules are much more complex and they
do not, as yet, have any such "helpful" aids. Life is like that
sometimes.
Gitolite allows you to set git repo options using the "config" keyword;
see conf/example.conf for details and syntax.
However, if you are in an installation where the repo admin does not
(and should not) have shell access to the server, then allowing him to
set arbitrary repo config options *may* be a security risk -- some
config settings may allow executing arbitrary commands.
This patch fixes it, introducing a new RC variable to control the
behaviour. See conf/example.gitolite.rc for details
Although I have washed my hands off the security aspect if you use
external commands, that doesn't mean I won't make them as tight as I can
;-) Right now, this is just a place holder -- if people use it and
complain that the pattern is too restrictive, I'll change it.
The wildrepos branch has been merged into master, and deleted. It will no
longer exist as a separate branch. Instead, a new variable
called $GL_WILDREPOS has been added which acts as a switch; when
off (which is the default), many wildrepos features are disabled.
(the "C" permissions, and the getperms (etc.) commands mainly).
Important: if you are using wildrepos, please set "$GL_WILDREPOS = 1;" in
the RC file when you upgrade to this version (or just before you do the
upgrade).
Allow users to set and display description (for gitweb) for their
own wildcard repositories using ssh commands:
setdesc <repo>
getdesc <repo>
Signed-off-by: Teemu Matilainen <teemu.matilainen@reaktor.fi>
brought on by realising that you lost $shell_allowed when refactoring
(previous commit) but perl hadn't caught it because -- damn -- you
didn't have "use strict" in gitolite.pm
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
great idea by Robin Smidsrød: since users are already capable of
authenticating themselves to gitolite via ssh keys, use that to let them
set or change their own HTTP passwords (ie, run the "htpasswd" command
with the correct parameters on behalf of the "git" user on the server)
code, rc para, and documentation. In fact everything except... ahem...
testing ;-)
and while we're about it, we also reorganised the way these helper
commands (including the venerable "info" are called)
Gitolite uses projects.list to set the owners for gitweb's use.
Unfortunately, this does not work for gitweb setups that set
$projectroot to a directory, thus generating the list of
repositories on the fly.
This patch changes that: gitolite now writes the gitweb.owner
configuration variable for each repository (and properly cleans up after
itself if the owner is removed).
The patch causes gitolite not to write the owner to projects.list
anymore, as this would be redundant.
The owner also needs no longer be escaped, so this patch removes the
poor man's 's/ /+/g' escaping previously in place.
Note that I am not a Perl coder. Thus there are probably better ways to
implement this, but at least it works.
Cc: Sitaram Chamarty <sitaramc@gmail.com>
Signed-off-by: martin f. krafft <madduck@madduck.net>
This is actually a pretty big deal, and I am seriously starting wonder
if calling this "gito*lite*" is justified anymore.
Anyway, in for a penny, in for a pound...
This patch implements a generic way to allow access control for external
commands, as long as they are invoked via ssh and present a server-side
command that contains enough information to make an access control
decision.
The first (and only, so far) such command implemented is rsync.
Please read the changes in this commit (at least the ones in conf/ and
doc/) carefully.
Mpenz asked what would happen if the config looked like
repo foo/abc
R sitaram
repo foo/.*
RW sitaram
If you asked for an expand of '.*', it would pick up permissions from
the second set (i.e., "RW") and print them against "foo/abc".
This is misleading, since those are not the permissions that will
actually be *used*. Gitolite always uses the more specific form if it
is given, which means your actual permissions are just "R".
This patch is to prevent that misleading reporting in this corner case.
- see *all* wildcard repos you have access to (this uses line-anchored
regexes as described in doc/4). Examples:
ssh git@server expand '.*'
ssh git@server expand 'assignment.*'
- show perms like the info command does
Please see comments against 02cee1d for more details and caveats.
The "msysgit doesnt have 'comm'" commit (from 2 days ago), had 2 bugs:
- (smaller) the "+++" which was part of the diff header was triggering
a spurious rc file "new variables" warning, but there were no actual
variables to update
- (bigger) worse, the grep command, when there were no matches,
coupled with the "set -e" to kill the program right there (ouch!)
The way pubkey files are handled by gitolite, this could be used by a
repo admin to get shell access. It's always been there as an
undocumented emergency mechanism for an admin who lost his shell keys or
overwrote them due to not understanding ssh well enough (and it has been
so used at least once).
But not any more...
Like the @SHELL case, this reflects a shift away from treating people
with repo admin rights as eqvt to people who have shell on the server,
and systematically making the former lesser privileged than the latter.
While in most cases (including my $DAYJOB) these two may be the same
person, I am told that's not a valid assumption for others, and there've
been requests to close this potential loophole.
Stop conflating the privilege to push changes to the admin repo with the
privilege to get a shell on the server.
Please read doc/6 carefully before upgrading to this version. Also
please ensure that the gitolite key is *not* your only means to get a
command line on the server
Currently, a line like
RW foo = user1
allows user1 to push any ref that contains the string refs/heads/foo.
This includes refs like
refs/heads/foo
refs/heads/foobar
refs/heads/foo/bar
which is fine; that is what is intended. (You can always use foo$
instead of foo if you want to prevent the latter two).
Similarly,
RW refs/foo = user1
allows
refs/foo
refs/foobar
refs/foo/bar
Now, I don't see this as a "security risk" but the fact is that this
allows someone to clutter your repo with junk like
refs/bar/refs/heads/foo
refs/heads/bar/refs/heads/foo
(or, with the second config line example,
refs/bar/refs/foo
refs/heads/bar/refs/foo
)
My personal advice is if you find someone doing that intentionally, you
should probably take him out and shoot him [*], but since now *two*
people have complained about this, here goes...
----
[*] you don't have to take him out if you don't want to
gitolite specific ssh commands ("getperms", "setperms", "info" etc.)
should exit with non-error code in case of success.
Also "get/setperms" should print to STDOUT instead of STDERR.
This change is specially needed for the gitolite-tools
(http://github.com/tmatilai/gitolite-tools) to work.
Signed-off-by: Teemu Matilainen <teemu.matilainen@reaktor.fi>
Support config file including using:
include "filename"
If filename is not an absolute path, it is looked from the
$GL_ADMINDIR/conf/ directory.
For security reasons include is not allowed for fragments.
Signed-off-by: Teemu Matilainen <teemu.matilainen@reaktor.fi>
This is a backward incompatible change. If you are using delegation and
you upgrade to this version, please do the following:
* change your gitolite.conf file to use the new syntax (see
doc/5-delegation.mkd in this commit)
* for each branch "foo" in the gitolite-admin repo, do this:
# (on "master" branch)
git checkout foo -- conf/fragments/foo.conf
* git add all those new fragments and commit to master
* delete all the branches on your clone and the server
# again, for each branch foo
git branch -D foo
git push origin :foo
(this commit will probably get reverted after a suitable period has
elapsed and no one is likely to still be using the old syntax).
Forgetting to change it to NAME/ after is a security issue -- you end up
permitting stuff you don't want to!
This commit allows the old syntax but prints a warning
Gitolite allows you to restrict changes by file/dir name. The syntax
for this used "PATH/" as a prefix to denote such file/dir patterns.
This has now been changed to "NAME/" because PATH is potentially
confusing.
While this is technically a backward-incompatible change, the feature
itself was hitherto undocumented, and only a few people were using it,
so I guess it's not that bad...
Also added documentation now.
This reverts commit 6576e82e33.
On oddball configs, where the shell key is reused as the gitolite key by
smart( people|-alecks), the ls-remote stops the program dead, preventing
the "git add" and "git commit" that seed the admin repo.
This makes extra work in terms of fixing it after the fact; removing it
makes the install go further, and all you need to do is (1) delete the
first line from ~/.ssh/authorized_keys on the server and (2) back on the
client do a "git clone gitolite:gitolite-admin".
OK so it needs to be removed. Explaining that was the easy part! The
hard part is explaining why removing it is harmless.
Look at the commit tree around that commit, and see that the commit
before that (b78a720) was partially reverted in e7e6085. b78a720
removed the new_repo call from compile, forcing it to happen only on
auth, which forced this workaround for seeding the admin repo.
Since e7e6085 reverted that part of b78a720, giving back new_repo
functions to compile, this line of code wasn't doing any good. QED and
all that :)
for those not yet able to upgrade (or until I merge this into the branch
you care about), if you have a repo called, say "bk2git", just refer to
it as "bk2git.git" in the clone command!
[Thanks to Mark Frazer for finding this...]
"repo @all" can be used to set permissions or configurations for all
already defined repos. (A repository is defined if it has permission
rules associated, empty "repo" stanza or "@group=..." line is not enough.)
For example to allow a backup user to clone all repos:
# All other configuration
[...]
repo @all
R = backup
Signed-off-by: Teemu Matilainen <teemu.matilainen@reaktor.fi>
we've removed the facility of auto-viving "W" access repos when they are
not wildcards. A wildcard pattern like foo/CREATER was
indistinguishable from a non-wildcard repo, and resolving it was
becoming kludgier and kludgier. (See the revert in the commit before
this one for details).
As a side effect of not being able to distinguish wildcard repos from
real repos easily, the expand command now works for a normal repo too
(because we have to make it work for "foo/CREATER")
This reverts commit 33fc0a7e9f.
Was causing too much trouble with access reporting (basic and expanded)
because of the extra ^ at the start...
The paranoia referred to in that commit was this sequence:
- admin creates a named (non wildcard) repo using config file push
- somehow that gets deleted (OS error, corruption, ...)
- admin just asks anyone with a current repo to push it to auto-revive
it (because we allow people with "W" access to non-wildcard repos to
auto-viv repos)
- if you're treating this the same as a wildcard creation, you end up
making this guy the "creater" of that repo, which means he can add
users etc...
We resolve that paranois by disallowing autoviv of "W" access repos at
all... Only "C" access repos can be autovived by a user (this will be
in the next commit)
".../gl-auth-command username" is the normal command that authkeys
forces, and this prevents that key from being used to get a shell.
We now allow the user to get a shell if the forced command has a "-s"
before the "username", like ".../gl-auth-command -s sitaram".
(Now that a plain "ssh gitolite" gets you a shell, there's a new "info"
command that such privileged keys can use to get basic access info).
Thanks to Jesse Keating for the idea! I can't believe this never
occurred to me before, but I guess I was so enamoured of my "innovation"
in converting what used to be an error into some useful info I didn't
think a bit more :/
Looks like I'd forgotten this when I did the autoviv code. Repos
created via gl-compile (when you add a new repo to the config file and
push) worked fine, but repos created via gl-auth (when you autoviv a
repo, wild or not) did not.
This *should* be merged into wildrepos soon after testing; wildrepos
will have a lot more autoviv-ing than master.
The admin repo's post-update hook needs to know where $GL_ADMINDIR is,
and we had a weird way of doing that which depended on gl-install
actually munging the hook code.
We also always assumed the binaries are in GL_ADMINDIR/src.
We now use an env var to pass both these values. This removes the weird
dependency on gl-install that the post-update hook had, as well as make
running other programs easier due to the new $GL_BINDIR env var.
...like "git clone host:foo/", even if it matches "repo foo/.*"
NOTE: I expect a few more of these special cases to be found as time
goes on and people find new ways to abuse the regex system, whether it
is done intentionally or not. Anything not fixable by changing the
config file will be fixed in the code asap.
This one, for instance, seems fixable by using "foo/.+" instead of
"foo/.*". But it actually isn't; the user can do "git clone host:foo//"
and bypass that :(
Still I suspect most situations will get an entry in the "then don't do
that" file :)
----
patient: "doc, it hurts when I do this"
doc: "then don't do that"
Teemu's testing brought up a situtation I had not anticipated:
"repo foo/CREATER" looks like a non-regex, and its creation then (a)
goes by "W" permissions instead of "C" permissions, and (b) the
creater's name does not get recorded (no gl-creater file).
SIDE NOTE: one way is to reduce the paranoia, and just put the
creater name in anyway. Treat a repo created from gl-auth as a
wildcard-matched autovivified repo, because the *other* kind would
have actually got created by gl-compile anyway.
However, I can think of *one* very far-out situation where this
could backfire on an unwary admin, and I'm paranoid :-)
So we need to force it to look like a regex. Moving the line-anchoring
from `parse_acl` to gl-compile sounded fine, until I realised that the
"$" isn't easy. Backslashitis, bigtime, plus the single/double quote
tricks we're playing with the dumped hash adds its own complexities.
Best of both worlds, promote the "^" to gl-compile, keep the "$" where
it is...!
Git repository configurations can be set/unset by declaring "config"
lines in "repo" stanzas in gitolite.conf. For example:
repo gitolite
config hooks.mailinglist = gitolite-commits@example.tld
config hooks.emailprefix = "[gitolite] "
config foo.bar = ""
config foo.baz =
The firs two set (override) the values. Double quotes must be used to
preserve preceding spaces. Third one sets an empty value and the last
removes all keys.
Signed-off-by: Teemu Matilainen <teemu.matilainen@reaktor.fi>
we had usurped the email style syntax to separate multiple keys
belonging to the same person, like sitaram@desktop.pub and
sitaram@laptop.pub. If you have so many users that you need the full
email address to disambiguate some of them (or you want to do it for
just plain convenience), you couldn't.
This patch fixes that in a backward compatible way. See
doc/3-faq-tips-etc.mkd for details.
This feature has *no* warranty, and so no documentation. Not more than
this transcript anyway.
config file:
@prof = u1
@TAs = u2 u3
@students = u4 u5 u6
repo assignments/CREATER/a[0-9][0-9]
C = @students
RW+ = CREATER
RW = WRITERS @TAs
R = READERS @prof
session:
as user "u4":
# check your permissions
$ ssh git@server
PTY allocation request failed on channel 0
hello u4, the gitolite version here is v0.95-31-gbcb14ca
you have the following permissions:
C assignments/CREATER/a[0-9][0-9]
@ @ testing
Connection to localhost closed.
# autovivify repos for assignment 12 and 24
$ git clone git@server:assignments/u4/a12 a12
Initialized empty Git repository in /home/sitaram/t/a12/.git/
Initialized empty Git repository in /home/gitolite/repositories/assignments/u4/a12.git/
warning: You appear to have cloned an empty repository.
$ git clone git@server:assignments/u4/a24 a24
Initialized empty Git repository in /home/sitaram/t/a24/.git/
Initialized empty Git repository in /home/gitolite/repositories/assignments/u4/a24.git/
warning: You appear to have cloned an empty repository.
# check what repos you autovivified
$ ssh git@server expand assignments/u4/a[0-9][0-9]
(u4) assignments/u4/a12
(u4) assignments/u4/a24
as user "u5":
# check your basic permissions
$ ssh git@server
PTY allocation request failed on channel 0
hello u5, the gitolite version here is v0.95-31-gbcb14ca
you have the following permissions:
C assignments/CREATER/a[0-9][0-9]
@ @ testing
Connection to localhost closed.
# see if you have access to any of u4's repos
$ ssh git@server expand assignments/u4/a[0-9][0-9]
# (no output produced)
as user "u4":
# allow "u5" read access to assignment 12
# note you type in "R u5", hit enter, then hit Ctrl-D. Gitolite
# then produces a confirmation message starting "New perms are:"
$ ssh git@server setperms assignments/u4/a12
R u5
New perms are:
R u5
as user "u5":
# again see if you have access to any u4 repos
$ ssh git@server expand assignments/u4/a[0-9][0-9]
(u4) assignments/u4/a12
as user "u4":
# check what permissions you gave to assignment 12
$ ssh git@server getperms assignments/u4/a12
R u5
# add RW access to "u6" to assignment 12
# again, type 'em in, then hit Ctrl-D; and note each time you run
# this you're starting from scratch -- you can't "add to" the
# permissions. Deal with it...
$ ssh git@server setperms assignments/u4/a12
R u5
RW u6
New perms are:
R u5
RW u6
as user "u6":
# check what u4 stuff you have access to
$ ssh git@server expand assignments/u4/a[0-9][0-9]
(u4) assignments/u4/a12
- new_repo now takes a "creater" parameter; if given, this user is
recorded (in a file called "gl-creater") as the creater of the repo.
Only applicable to wildcards
- repo_rights reads "gl-creater" and "gl-perms" to tell you who
created it, and whether you (the $user) are in the list of READERS
or WRITERS
**NOTE** that the mechanism to create/update gl-perms has not been
written yet... (as of this commit)
- parse_acl takes 4 more arguments, all optional. The repo name we're
interested in (set by all except the access reporting function), and
the names to be interpolated as $creater, $readers, writers
- report_basic now knows about the "C" permission and shows it
- auth now autovivifies a repo if the user has "C" and it's a wildcard
match, or (the old case) the user has "W" and it's not a wildcard.
In the former case, the creater is also set
IMPLEMENTATION NOTES:
- the Dumper code now uses a custom hash key sort to make sure
$creater etc land up at the *end*
- a wee bit of duplication exists in the update hook; it borrows a
little code from parse_acl. I dont (yet) want to include all of
gitolite.pm for that little piece...
There's a new "C" permission to let someone *create* a repo that matches
the pattern given in the "repo ..." line. If the word CREATER appears
in the repo pattern, then that is forced to the actual user performing
that operation.
Something like this (we'll discuss READERS and WRITERS later):
repo personal/CREATER/.+
C = @staff
R [foo] = READERS
RW [bar] = WRITERS
...various other permissions as usual...
Delegation checking also changes quite a bit... see comments in code
Implementation: there's also a sneaky little trick we're playing here
with the dumped hash
all of this is prep for the upcoming, all-new, chrome-plated,
"wildrepos" branch :)
- many variables go to gitolite.pm now, and are "our"d into the other
files as needed
- new functions parse_acl, report_basic to replace inlined code
consider:
repo = "some desc" # some comment
(and note that the regex for recognising a description expects that
dblquote to be the *last* character on the line)
part of comment on b78a720cee:
The only reason it's getting into master is because it looks cool!
I hate it when something that looks cool doesn't work right :(
creating a repo on gitolite-admin push is *needed* in order to get
descriptions and export-ok files to work right
Summary: much as I did not want to use "excludes", I guess if we don't put the
code in "master" it's OK to at least *write* (and test) the code!
See the example config file for how to use it.
See "design choices" section in the "faq, tips, etc" document for how it
works.
the "create a new repo" code moves from compile to auth.
Only someone who has W access can create it, but he can do so even on a
"R" operation (like clone or ls-remote).
This is a pre-requisite for rebel's wildcard repos, where
autovivification is the only way you can create arbitrary repos matching
a pattern.
The only reason it's getting into master is because it looks cool!
----
OK that's a lie; the real reason is to keep the two branches as similar
as possible, though they;ve diverged quite a bit since the "only
one-line difference" days where "rebel" just meant "deny/exclude"
rules!)
writing the export_ok files and the gitweb project list are now
unconditional. They're idempotent anyway, and I doubt anyone cared
about all the fancy logic to detect and report *just* the new ones on
each compile.
This paves the way for gitweb ownership to be added later; that code was
becoming too complex otherwise...
- refuse to install to root
- when a pubkey is being used that was not freshly created by
ourselves, warn the user that this key can not be used to get shell
access to the server. Prevents some corner cases of people being
locked out...
Also, change the final message to be even more clear that this is all on
the workstation, not the server
I don't have a use for "@all" at all (pun not intended!) other than the
"testing" repo, but <teemu dot matilainen at iki dot fi> sent in a patch
to mark those repos with "R" and "W" in the permissions list, and I
started thinking about it.
This could actually be useful if we *differentiated* such access from
normal (explicit username) access. From the "corporate environment"
angle, it would be nice if a project manager could quickly check if any
of his projects have erroneously been made accessible by @all.
So what we do now is print "@" in the corresponding column if "@all" has
the corresponding access.
Also, when someone has access both as himself *and* via @all, we print
the "@"; printing the "R" or "W" would hide the "@", and wouldn't
correctly satisfy the use case described above.
We detect an upgrade situation by the presence of
$GL_ADMINDIR/conf/gitolite.conf -- if it exists, we reason, this is not
a fresh install. And if so we skip setting up PTA, and the initial
clone.
Well, turns out this is not always true. I've had a few cases where the
first install didn't go right, but left enough stuff in to make the
subsequent attempt think this is an upgrade.
[This mostly happened to me when I was testing the "oldgits" branch, and
also when I was making it work from msysgit I think... regardless of
why, it'd be good to fix]
So this changes the flow somewhat. Now the *only* difference between a
fresh install and an ugrade is the "initial_conf_key" function call (you
don't want to overwrite an existing conf file or keydir!)
I was trying to determine how close gitolite can come to the ACL model
of a proprietary product called codebeamer, and one of the items was how
to make a "role" (like QA_Lead) have different "members" in different
projects.
I then realised delegation already does that! Which is great, but as I
thought about it more, I realised... well, we'll let the in-code
comments speak for themselves :-)
Anyway, all it needed was a 1-line fix, luckily... <phew> And it would
have only affected people who use delegation.
- all $HOME/blah becomes "$HOME/blah" (bl**dy "Documents and Settings" crap)
- replace bash regex with perl, and in one case replace the check with
something else
- rsync changed to appropriate scp
- since we no longer insist on running from a specific directory, create
tmpgli dir *after* you cd to the right place
You can now add your own hooks into src/hooks/ and they get propagated
along with the update hook that is present there now. Please read the
new section in the admin document, and make sure you understand the
security implications of accidentally fiddling with the "update" script.
This also prompted a major rename spree of all the files to be
consistent, etc. Plus people said that the .sh and .pl suffixes should
be avoided (and I was feeling the same way). I've also been
inconsistent with that "gl-" prefix, so I cleaned that up, and the 00-
and 99- were also funny animals.
Time to get all this cleaned up before we get 1.0 :)
So these are the changes, in case you're looking at just the commit
message and not the diffstat:
src/pta-hook.sh -> src/ga-post-update-hook
src/conf-convert.pl -> src/gl-conf-convert
src/00-easy-install.sh -> src/gl-easy-install
src/99-emergency-addkey.sh -> src/gl-emergency-addkey
src/install.pl -> src/gl-install
src/update-hook.pl -> src/hooks/update
**upgrades no longer touch the config or the keydir**
When you first install gitolite, the easy install script has to do two
*distinct* things:
* install the software
* create and seed the gitolite-admin repo with a minimum config file
and the newly created pubkey
That's fine for an install, because nothing exists yet anyway.
Subsequent invocations of the script should only do the first task (so
that gitolite itself can be upgraded), and not attempt to fiddle with
the config file and pubkeys.
Unfortunately, until now I had not been separating these two activities
cleanly enough. For instance, the commit message for 8e47e01 said:
IMPORTANT: we assume that $admin_name remains the same in an upgrade
-- that's how we detect it is an upgrade! Change that name or his
pubkey, and you're toast!
Ouch!
So now I decided to clean things up. The "Usage" message tells you
clearly what to do for an upgrade.
Should have been like this from the beginning, but hey we got there
eventually :)
----
Code-wise, this is a major refactor of the easy install script. It uses
an old forgotten trick to get forward refs for bash functions ;-) and in
the process cleans up the flow quite a bit.
- "it's an upgrade" is decided by presence of gitolite.conf (not a pubkey)
- admin_name optional (and will be ignored if given) for upgrades
plus a lot of comments and some minor text changes
Packaging gitolite for debian requires the rc file to be in /etc/gitolite.
But non-root installs must still be supported, and they need it in $HOME.
This means the rc file is no longer in a fixed place, which needs code to find
the rc file first. See comments inside new file 'gitolite.pm' for details.
The rest of the changes are in the other programs, to replace the hard-coded
rc filename with a call to this new code.
- example config file is now all comments (should have been that way anyway)
- we detect if it is an upgrade and act accordingly (see below)
IMPORTANT: we assume that $admin_name remains the same in an upgrade -- that's
how we detect it is an upgrade! Change that name or his pubkey, and you're
toast!
- added comments to easy install to help do it manually
- README: some stuff moved to tips doc, brief summary of extras
(over gitosis) added
- INSTALL: major revamp, easy install and manual install,
much shorter and much more readable!
plus other docs changed as needed, and updated the tips doc to roll in
some details from "update.mkd" in the "ml" branch
- add better comments on the 2 main hashes
- work around an inefficiency caused by the exclude prep code needing
a list instead of a hash at a certain place
[Note: this is a fairly involved commit, compared to most of the others.
See doc/5-delegation.mkd for a user-level feature description.]
parse delegated config fragments (found as conf/fragments/*.conf). Any
repos being referenced within a fragment config *must* belong to the
"@group" with the same name as the fragment.
That is, a fragment called conf/fragments/abc.conf can only refer to repos
that are members of the "@abc" repo group. It cannot specify access
control for any other repos. If it does, those settings are ignored, and
a warning message is produced.
since the delegated config must have the flexibility of (re-)defining
group names for internal convenience, and since all such definitions go
into the same "groups" hash, it is quite easy for conf/fragments/abc.conf
to write in its own (re-)definition of "@abc"! That would be a neat
little security hole :)
The way to close it is to consider only members of the "@abc" groupset
defined in the main ("master") config file for this purpose.
collect the delegated config fragments from correspondingly named branches of
the gitolite-admin repo, and put them all in conf/fragments/
also deprecate changes to conf and keydir locations from now on
Again, prep for delegation, when we'll be reading fragments of config rules
from various files and tacking them onto the %repos hash.
note: this patch best viewed with "git diff -w", clicking "Ignore space
change" in gitk, or eqvt :-)
- warn about files in keydir/ that dont end with ".pub"
- warn about pubkey files for which the user is not mentioned in config
- warn more sternly about the opposite (user in config, no pubkey!)
update hook: add reponame to message on deny
auth: minor typo
Summary:
DONT forget to run src/gl-compile-conf as the last step in the upgrade
Details:
The compiled file format has changed quite a bit, to make it easier for the
rebel edition coming up :-)
compile:
- we don't split RW/RW+ into individual perms anymore
- we store the info required for the first level check separately now:
(repo, R/W, user)
- the order for second level check is now:
repo, user, [{ref=>perms}...] (list of hashes)
update hook logic: the first refex that:
- matches the incoming ref, AND
- contains the perm you're trying to use,
causes the match loop to exit with success. Fallthrough is failure
- detect/warn git version < 1.6.2
- create documentation with details on client-side workaround
- change the "git init --bare" to (older) "git --bare init", since the old
syntax still works anyway
why should just usernames have all the fun :) The "expand_userlist" function
is now "expand_list" and serves generically. The example conf has also been
updated correspondingly
(thanks to SethX for feedback)
- install: a little more verbosity in the mkdir
- install and example conf: some of the help text made more clear
- auth: error message on bad $cmd is now clearer, plus no perl-warnings to
confuse people
- logs go into $GL_ADMINDIR/logs by default, named by year-month
- logfile name template (including dir prefix) now in $GL_LOGT
- two new env vars passed down: GL_TS and GL_LOG (timestamp, logfilename)
- log messages timestamps more compact, fields tab-delimited
- old and new SHAs cut to 14 characters