- make the warning less juvenile ;-) - de-emphasise the connection to wild repos; it's not as deep as the doc made it out to be - move the historical stuff out of the way
253 lines
9.9 KiB
Markdown
253 lines
9.9 KiB
Markdown
## admin defined commands
|
|
|
|
Summary: this document describes a mechanism to allow users controlled access
|
|
to specific programs or scripts, without giving them full shell access.
|
|
|
|
**WARNING**: careless use of this feature, including inadequate review of
|
|
allowed commands or scripts, could compromise this security and allow users to
|
|
grant themselves full shell access, accidentally or otherwise.
|
|
|
|
----
|
|
|
|
In this document:
|
|
|
|
* <a href="#_background">background</a>
|
|
* <a href="#_setting_it_up">setting it up</a>
|
|
* <a href="#_configuring_ADCs">configuring ADCs</a>
|
|
* <a href="#_anatomy_of_a_command">anatomy of a command</a>
|
|
* <a href="#_example_uses_and_sample_commands_in_contrib">example uses and sample commands in contrib</a>
|
|
* <a href="#_fork">fork</a>
|
|
* <a href="#_deleting_trashing_repos">deleting/trashing repos</a>
|
|
* <a href="#_enable_disable_push_access_temporarily">enable/disable push access temporarily</a>
|
|
* <a href="#_bonus_restricted_admin">(bonus) restricted admin</a>
|
|
* <a href="#_how_this_feature_came_about">how this feature came about</a>
|
|
|
|
----
|
|
|
|
<a name="_background"></a>
|
|
|
|
### background
|
|
|
|
Allowing users to get a shell is a no-no if you're using gitolite, but there
|
|
are times when you want them to be able to run specific commands or custom
|
|
scripts that you (the admin) have pre-approved to be "safe". Here's how to
|
|
enable such commands.
|
|
|
|
However, as the warning at the top says, careless use could allow users to
|
|
defeat this security and get a shell. Every command you approve must be
|
|
checked to be sure it cannot be compromised.
|
|
|
|
To help you with this, gitolite restricts ADCs arguments to only some very
|
|
safe characters (see `$ADC_CMD_ARGS_PATT` in `src/gitolite_rc.pm`). The code
|
|
inside the ADC, however, is *your* responsibility. The sample ADCs shipped
|
|
with gitolite (in `contrib/adc`) should be OK, but an extra pair of eyes never
|
|
hurt :-) so please review before installing them.
|
|
|
|
<font color="gray">
|
|
|
|
Finally, although this is a generic way to allow specific commands to be run,
|
|
most of the examples and sample ADCs pertain to allowing users to manage their
|
|
"own" repos. If that's your use case, please read
|
|
[doc/wildcard-repositories.mkd][wild] before you continue here.
|
|
|
|
</font>
|
|
|
|
<a name="_setting_it_up"></a>
|
|
|
|
### setting it up
|
|
|
|
This can only be setup by someone who has shell access to the server. Edit
|
|
the rc file and update the `$GL_ADC_PATH` variable to point to, say,
|
|
`/home/git/bin/adc`. *Nothing happens unless this variable is set and
|
|
pointing to a directory*. Then put in whatever such commands you create into
|
|
that directory. If you have a command called "foo" in that directory, then a
|
|
user can invoke it by saying:
|
|
|
|
ssh git@server foo argument list
|
|
|
|
**WARNING: When gitolite takes control, this directory is checked first, and
|
|
if the requested command exists, it is executed. It is therefore quite easy
|
|
to inadvertently *hide* some of the "official" commands (like "info",
|
|
"expand", "setperms", etc., or worse, say "git-upload-pack"!) by creating
|
|
executable files with those names in this directory. So don't do that -- you
|
|
have been warned!**
|
|
|
|
<a name="_configuring_ADCs"></a>
|
|
|
|
#### configuring ADCs
|
|
|
|
I didn't want to put configuration variables for ADCs also into the main 'rc'
|
|
file, so I chose to put them in the `adc.common-functions` file instead. Take
|
|
a look at it sometime.
|
|
|
|
<a name="_anatomy_of_a_command"></a>
|
|
|
|
### anatomy of a command
|
|
|
|
You can basically do whatever you want in such a command -- go wild! It's
|
|
upto you to check the permissions of *each* repo that the user is manipulating
|
|
using your command -- you can `rm -rf $GL_REPO_BASE_ABS` if you like and
|
|
gitolite wouldn't stop you.
|
|
|
|
The current directory (`$PWD`) will be set to the `$HOME` of `git@server` (or
|
|
whatever id you're using). It won't be any specific repo, it won't even be
|
|
the base directory of all the repos.
|
|
|
|
Gitolite defines a few environment variables, as well as allows you to
|
|
directly query the ownership and access permissions of any repository.
|
|
|
|
The environment variables available are:
|
|
|
|
* `GL_USER` -- the name of the user invoking the command
|
|
* `GL_BINDIR` -- the directory containing all the binaries (in particular,
|
|
`gitolite.pm`, which is all we really care about here)
|
|
* `GL_REPO_BASE_ABS` -- the absolute path of the base directory containing
|
|
all the repos
|
|
|
|
There are a few other variables also available but the above are the only ones
|
|
you should rely on. Please treat any other variables you notice as being
|
|
internal/undocumented/subject to change.
|
|
|
|
[Implementation note: some of the distro packagers don't seem to like
|
|
`GL_BINDIR`. I have not tested this in those scenarios, but they probably put
|
|
`gitolite.pm` somewhere in perl's lib path anyway, so it ought to work].
|
|
|
|
In addition, all the arguments of the command are also available to you, so
|
|
you can define your own command syntaxes. Gitolite checks these arguments to
|
|
make sure they fit a very conservative pattern (see `$ADC_CMD_ARGS_PATT` in
|
|
`src/gitolite.pm`), so take that into consideration when designing your
|
|
commands and usage.
|
|
|
|
Finally, you can call gitolite to query ownership and permissions for the
|
|
current user (which may not necessarily be the owner). This is done loosely
|
|
as follows (don't use this exact code yet though):
|
|
|
|
perl -I$GL_BINDIR -Mgitolite -e "cli_repo_rights('reponame')"
|
|
|
|
which will print two space-separated words: permissions and owner. Something
|
|
like `_____R__W u1` or maybe `____@R_@W <gitolite>`. (The `u1` indicates the
|
|
queried repo is a wildcard repo created by user `u1`; for meanings of the "@"
|
|
see doc/report-output.mkd)
|
|
|
|
But that's cumbersome. There's a bash shell function called
|
|
`get_rights_and_owner` in `contrib/adc/adc.common-functions` that is much more
|
|
convenient. See any of the other samples for how to use it.
|
|
|
|
If you don't like this, roll your own. If you don't like bash, do the eqvt in
|
|
your language of choice.
|
|
|
|
<a name="_example_uses_and_sample_commands_in_contrib"></a>
|
|
|
|
### example uses and sample commands in contrib
|
|
|
|
<a name="_fork"></a>
|
|
|
|
#### fork
|
|
|
|
A user would use the fork command like this:
|
|
|
|
ssh git@server fork from to
|
|
|
|
where "from" is a repo to which the user invoking the fork has "R" access, and
|
|
"to" is a repo that does not yet exist and to which he has "C" access.
|
|
|
|
(Reminder: these access checks are done by the "fork" script, **not** within
|
|
gitolite -- once again, you are responsible for making sure your scripts
|
|
maintain the security of the system!)
|
|
|
|
Strictly speaking this command is not really needed. Even without all this
|
|
"admin-defined commands" setup you could still do the following, purely from
|
|
the client side:
|
|
|
|
git clone git@server:from
|
|
cd from
|
|
git remote add new git@server:to
|
|
git push new refs/*:refs/*
|
|
|
|
or some such incantation.
|
|
|
|
<a name="rmrepo"></a>
|
|
|
|
<a name="_deleting_trashing_repos"></a>
|
|
|
|
#### deleting/trashing repos
|
|
|
|
See the [repo-deletion document][rdR] for details about this.
|
|
|
|
[rdR]: http://sitaramc.github.com/gitolite/contrib/adc/repo-deletion.html
|
|
|
|
<a name="_enable_disable_push_access_temporarily"></a>
|
|
|
|
#### enable/disable push access temporarily
|
|
|
|
If you want to disable push access to gitolite temporarily (maybe for
|
|
maintenance), anyone with write access to the gitolite-admin repo can do this:
|
|
|
|
ssh git@server able dis @all # able dis ==> dis able
|
|
|
|
To re-enable after the maint work is done:
|
|
|
|
ssh git@server able en @all # able en ==> en able
|
|
|
|
You can also do this for one or more individual repos; in place of `@all`,
|
|
just use a space separated list of reponames (exactly as they would appear in
|
|
the config file). Wildcards are not supported; patches welcome ;-)
|
|
|
|
Note: please see [this][diswr] for more on this.
|
|
|
|
[diswr]: http://sitaramc.github.com/gitolite/doc/3-faq-tips-etc.html#_disabling_write_access_to_take_backups
|
|
|
|
<a name="_bonus_restricted_admin"></a>
|
|
|
|
#### (bonus) restricted admin
|
|
|
|
It's rather important to me (and presumably others in the "corporate" world)
|
|
to separate permission to push to the "gitolite-admin" repo from unrestricted
|
|
shell access to the server. This issue has been visited often in the past.
|
|
|
|
Until now, though, this was binary -- you either had full shell access or none
|
|
at all. If there were tasks that legitimately needed to be done from the
|
|
shell on the server, it often meant you had to break that separation or load
|
|
the few people who did have shell access already.
|
|
|
|
Now, however, it is possible to provide scripts to do what you want, and put
|
|
them in `$GL_ADC_PATH`. `contrib/adc/restrict-admin` is a commented sample --
|
|
as you can see, it cleverly makes use of the fact that you can now check for
|
|
the invoking uses access to any repo in the system. In this case it checks if
|
|
he has "W" access to the gitolite-admin repo, and if he does, allows the
|
|
script to proceed.
|
|
|
|
[Note that this particular use does not require `$GL_WILDREPOS` to be enabled,
|
|
because it's not using any wildcard repos].
|
|
|
|
[xkcd224]: http://xkcd.com/224/
|
|
[lazy]: http://c2.com/cgi/wiki?LazinessImpatienceHubris
|
|
[wild]: http://sitaramc.github.com/gitolite/doc/wildcard-repositories.html
|
|
|
|
----
|
|
|
|
<a name="_how_this_feature_came_about"></a>
|
|
|
|
### how this feature came about
|
|
|
|
<font color="gray">
|
|
|
|
Gitolite was named to be short for "gitosis-lite". Someone now wants to turn
|
|
it into a "github-lite" :-) and even had some code to start me off thinking.
|
|
|
|
Since my first impulse on being asked for a feature is to say no, I was
|
|
casting about for a reason when he gave me one: he first made some noises
|
|
about perl, then said something about rewriting it all in scheme. Nice... I
|
|
resisted the urge to point him to [this][xkcd224], told him that's a great
|
|
idea and he should go for it, mentally blessing him for letting me off the
|
|
hook on coding it ;-) [Laziness][lazy] *is* the first virtue you know!
|
|
|
|
And that was that. For a couple of days.
|
|
|
|
Soon, though, I realised that there could be a pretty big bonus in this for
|
|
tightly controlled setups, so I went and coded it all anyway. See the section
|
|
on "restricted admin" for what's really exciting about this for *me*.
|
|
|
|
</font>
|
|
|