new method for passing usergroup info (warning: minor backward compat breakage)

The old method of passing in usergroup info had some problems, which are
now fixed.  It is also much easier to use now -- no more "wrapper"
script, plus it should work identially whether you use sshd or httpd.

See doc/big-config.mkd for details on the new method.

----

Notes on problems with the old method:

The old method for passing in usergroup info consisted of tacking them
on as extra arguments to gl-auth-command, after the username.

However, there are some problems with this method.

Some actions in gitolite look for permissions for users other than the
invoking user.  Determining permissions for gitweb and daemon is one.
An admin asking for "info" on some other user, is another.

However, the list of groups sent in via the command line
pertains only to the invoking user, so these actions don't work
correctly.  They may even pick up the wrong permissions.

What it all boils down to is that we need group information for any user
dynamically, instead of being passed a (static) list just for the
invoking user.
This commit is contained in:
Sitaram Chamarty 2010-10-07 16:36:14 +05:30
parent ba39d93e28
commit db0485fa7e
4 changed files with 65 additions and 40 deletions

View file

@ -273,6 +273,18 @@ $GL_WILDREPOS = 0;
# $GL_SITE_INFO = "";
# $GL_SITE_INFO = "XYZ.COM DEVELOPERS: PLEASE SEE http://xyz.com/gitolite/help first";
# --------------------------------------
# USERGROUP HANDLING
# Some sites would like to store group membership outside gitolite, because
# they already have it in (usually) their LDAP server, and it doesn't make
# sense to be forced to duplicate this information.
# Set the following variable to the name of a script that, given a username as
# argument, will return a list of groups that she is a member of.
# $GL_GET_MEMBERSHIPS_PGM = "/usr/local/bin/expand-ldap-user-to-groups"
# --------------------------------------
# per perl rules, this should be the last line in such a file:
1;

View file

@ -6,7 +6,9 @@ In this document:
* <a href="#_how_do_we_use_it_">how do we use it?</a>
* <a href="#_other_optimisations">other optimisations</a>
* <a href="#_what_are_the_downsides_">what are the downsides?</a>
* <a href="#_extra_coolness_usergroups_and_LDAP_similar_tools">(extra coolness) usergroups and LDAP/similar tools</a>
* <a href="#_storing_usergroup_information_outside_gitolite_like_in_LDAP_">storing usergroup information outside gitolite (like in LDAP)</a>
* <a href="#_why">why</a>
* <a href="#_how">how</a>
<a name="_when_why_do_we_need_it_"></a>
@ -190,51 +192,58 @@ subset of the allowed @fragname, which would work normally, do not work now).
(If you didn't understand all that, you're probably not using delegation, so
feel free to ignore it!)
<a name="_extra_coolness_usergroups_and_LDAP_similar_tools"></a>
<a name="_storing_usergroup_information_outside_gitolite_like_in_LDAP_"></a>
### (extra coolness) usergroups and LDAP/similar tools
### storing usergroup information outside gitolite (like in LDAP)
[Please NOTE: this is all about *user* groups, not *repo* groups]
Gitolite now allows usergroup information to be passed in from outside. The
`gl-auth-commmand` can now take an optional list of usergroup names after the
first argument (which is the username).
[WARNING: the earlier method of doing this has been discontinued; please see
the commit message for details]
To understand why this is useful, consider the following:
Gitolite now allows usergroup information to be stored outside its own config
file. We'll see "why" first, then the "how".
Some people have an LDAP-backed ssh daemon (or some other similar mechanism
that can speak "ssh" to the client), with pubkeys stored in LDAP, etc., and
some way (not using `~/.ssh/authorized_keys`) of invoking gitolite.
<a name="_why"></a>
Such setups also have "usergroups", and a way to tell, for each user, what
groups he/she is a member of. So let's say "alice" works on projects "foo"
and "bar", while "bob" works on project "bar" and is a member of the
`L3_support` team.
#### why
You can use those group names in the gitolite config file for access control
as "@foo", "@bar", `@L3_support`, etc.; please note the "@" prefix because
gitolite requires it.
Large sites often have LDAP servers that already contain user and group
information, including group membership details. Such sites may prefer that
gitolite just pick up that info instead of having to redundantly put it in
gitolite's config file.
However, that still leaves a wee little inconvenience. You still have to add
lines like this to the gitolite config file:
Consider this example config for one repo:
@foo = alice
@bar = alice bob
@L3_support = bob
repo foo
RW+ = @lead_devs
RW = @devs
R = @interns
You don't need to do that anymore now. Tell your authentication system that,
after authenticating alice, instead of running:
Normally, you would also need to specify:
/some/path/to/gl-auth-command alice
@lead_devs = dilbert alice
@devs = wally
@interns = ashok
it should first find the groups that alice is a member of, and then run:
However, if the corporate LDAP server already tags these people correctly, and
if there is some way of getting that information out **at run time**, that
would be cool.
/some/path/to/gl-auth-command alice foo bar
<a name="_how"></a>
That's it. Internally, gitolite will behave as if the config file had also
specified:
#### how
@foo = alice
@bar = alice
All you need is a script that, given a username, queries your LDAP or similar
server, and returns a space-separated list of all the groups she is a member
of. If an invalid user name is sent in, or the user is valid but is not part
of any groups, it should print nothing.
This script will probably be specific to your site. [**Help wanted**: I don't
know LDAP, so if someone wants to contribute some sample code I'd be happy to
put it in contrib/, with credit of course!]
Then set the `$GL_GET_MEMBERSHIPS_PGM` variable in the rc file to the full
path to this program, set `$GL_BIG_CONFIG` to 1, and that will be that.
[gwd]: http://github.com/sitaramc/gitolite/blob/pu/doc/3-faq-tips-etc.mkd#gwd

View file

@ -40,7 +40,7 @@ our $REPOPATT_PATT=qr(^\@?[0-9a-zA-Z[][\\^.$|()[\]*+?{}0-9a-zA-Z._\@/-]*$);
our $ADC_CMD_ARGS_PATT=qr(^[0-9a-zA-Z._\@/+-]*$);
# these come from the RC file
our ($REPO_UMASK, $GL_WILDREPOS, $GL_PACKAGE_CONF, $GL_PACKAGE_HOOKS, $REPO_BASE, $GL_CONF_COMPILED, $GL_BIG_CONFIG, $GL_PERFLOGT, $PROJECTS_LIST, $GL_ALL_INCLUDES_SPECIAL, $GL_SITE_INFO);
our ($REPO_UMASK, $GL_WILDREPOS, $GL_PACKAGE_CONF, $GL_PACKAGE_HOOKS, $REPO_BASE, $GL_CONF_COMPILED, $GL_BIG_CONFIG, $GL_PERFLOGT, $PROJECTS_LIST, $GL_ALL_INCLUDES_SPECIAL, $GL_SITE_INFO, $GL_GET_MEMBERSHIPS_PGM);
our %repos;
our %groups;
our %repo_config;
@ -932,6 +932,7 @@ sub special_cmd
# - (only for repos) as an indirect wildcard (@g = foo/.*; repo @g).
# note: the wildcard stuff does not apply to username memberships
our %extgroups_cache;
sub get_memberships {
my $base = shift; # reponame or username
my $is_repo = shift; # some true value means a repo name has been passed
@ -969,10 +970,17 @@ sub get_memberships {
# deal with returning user info first
unless ($is_repo) {
# add in group membership info sent in via second and subsequent
# arguments to gl-auth-command; be sure to prefix the "@" sign to each
# of them!
push @ret, map { s/^/@/; $_; } split(' ', $ENV{GL_GROUP_LIST}) if $ENV{GL_GROUP_LIST};
# bring in group membership info stored externally, by running
# $GL_GET_MEMBERSHIPS_PGM if it is defined
if ($extgroups_cache{$base}) {
push @ret, @{ $extgroups_cache{$base} };
} elsif ($GL_GET_MEMBERSHIPS_PGM) {
my @extgroups = map { s/^/@/; $_; } split ' ', `$GL_GET_MEMBERSHIPS_PGM $base`;
$extgroups_cache{$base} = \@extgroups;
push @ret, @extgroups;
}
return (@ret);
}

View file

@ -114,10 +114,6 @@ if ($ENV{REQUEST_URI}) {
$user=$ENV{GL_USER}=shift;
}
# if there are any more arguments, they're a list of group names that the user
# is a member of
$ENV{GL_GROUP_LIST} = join(" ", @ARGV) if @ARGV;
# ----------------------------------------------------------------------------
# logging, timestamp env vars
# ----------------------------------------------------------------------------