The "fork" adc cannot simply do a "git clone..."; hooks and gl-creater
won't get set up. We need a way to initiate the *creation* of a repo
from a shell command, and then fetch the refs over.
For a long time, we used to trick gitolite into creating a repo for us
by simply using "git ls-remote host:reponame" ;-) Now we have an actual
command, so we can say "ssh git@server git-init \'reponame\'"
Yes; those single quotes are required. Deal with it.
This commit series allows an admin to designate a set of commands that
users can run. For example, he can allow users to delete a repo that
they have created:
ssh git@server rmrepo foo/me/bar
or fork (to use github's terminology) a repo they have "R" access to,
into a new one they have "C" access to:
ssh git@server fork foo/someone-else/bar foo/me/bar
Please see documentation for details
----
(this commit)
- (rc) new variable $GL_ADC_PATH; without this none of this is enabled
- (pm) new helper routine "cli_repo_rights" to get rights/ownership
from outside
- (auth) call $GL_ADC_PATH/$cmd if it exists
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
SECURITY NOTE: if you deleted or renamed a pubkey file after 5fd9328
went in (April 12th), please:
- upgrade asap, then
- go to your latest gitolite-admin clone and "git push -f"
Otherwise this is not urgent.
5fd9328 (and its minor successor 813a2a9) were about preventing the
gitolite admin from sneaking in files to src/ and hooks/ into
$GL_ADMINDIR. It seemed easy enough to do this by converting the
path-less checkout to a with-paths checkout, but this has caused a worse
problem -- deleting a keydir/foo.pub now no longer has an effect; the
file still hangs around in the work tree.
Ouch! (and thanks to teukka for noticing)
We now do this check as a separate step, so the checkout can revert to
being path-less.
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.
This is a pretty big hole, really. Only the fact that Eli called it an
"accidental feature" helped catch it :)
Notes on the code:
An explicit list of paths -- maybe just "conf", "keydir", and "local" --
would have been easier, but this isn't too bad, I think.
people with shell access should be allowed to bypass the update hook, to
allow them to clone locally and push. You can now do this by setting an
env var that the ssh "front door" will never set, like so:
GL_BYPASS_UPDATE_HOOK=1 git push
Note that this will NOT work for the gitolite-admin repo, because the
post-update hook on that one requires a bit more. If you really want to
do that, try:
GL_ADMINDIR=~/.gitolite GL_BINDIR=~/.gitolite/src GL_BYPASS_UPDATE_HOOK=1 git push
(assuming default values in ~/.gitolite.rc)
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.