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 = "";
# $GL_SITE_INFO = "XYZ.COM DEVELOPERS: PLEASE SEE http://xyz.com/gitolite/help first"; # $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: # per perl rules, this should be the last line in such a file:
1; 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="#_how_do_we_use_it_">how do we use it?</a>
* <a href="#_other_optimisations">other optimisations</a> * <a href="#_other_optimisations">other optimisations</a>
* <a href="#_what_are_the_downsides_">what are the downsides?</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> <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 (If you didn't understand all that, you're probably not using delegation, so
feel free to ignore it!) 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] [Please NOTE: this is all about *user* groups, not *repo* groups]
Gitolite now allows usergroup information to be passed in from outside. The [WARNING: the earlier method of doing this has been discontinued; please see
`gl-auth-commmand` can now take an optional list of usergroup names after the the commit message for details]
first argument (which is the username).
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 <a name="_why"></a>
that can speak "ssh" to the client), with pubkeys stored in LDAP, etc., and
some way (not using `~/.ssh/authorized_keys`) of invoking gitolite.
Such setups also have "usergroups", and a way to tell, for each user, what #### why
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.
You can use those group names in the gitolite config file for access control Large sites often have LDAP servers that already contain user and group
as "@foo", "@bar", `@L3_support`, etc.; please note the "@" prefix because information, including group membership details. Such sites may prefer that
gitolite requires it. 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 Consider this example config for one repo:
lines like this to the gitolite config file:
@foo = alice repo foo
@bar = alice bob RW+ = @lead_devs
@L3_support = bob RW = @devs
R = @interns
You don't need to do that anymore now. Tell your authentication system that, Normally, you would also need to specify:
after authenticating alice, instead of running:
/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 #### how
specified:
@foo = alice All you need is a script that, given a username, queries your LDAP or similar
@bar = alice 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 [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._\@/+-]*$); our $ADC_CMD_ARGS_PATT=qr(^[0-9a-zA-Z._\@/+-]*$);
# these come from the RC file # 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 %repos;
our %groups; our %groups;
our %repo_config; our %repo_config;
@ -932,6 +932,7 @@ sub special_cmd
# - (only for repos) as an indirect wildcard (@g = foo/.*; repo @g). # - (only for repos) as an indirect wildcard (@g = foo/.*; repo @g).
# note: the wildcard stuff does not apply to username memberships # note: the wildcard stuff does not apply to username memberships
our %extgroups_cache;
sub get_memberships { sub get_memberships {
my $base = shift; # reponame or username my $base = shift; # reponame or username
my $is_repo = shift; # some true value means a repo name has been passed 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 # deal with returning user info first
unless ($is_repo) { unless ($is_repo) {
# add in group membership info sent in via second and subsequent # bring in group membership info stored externally, by running
# arguments to gl-auth-command; be sure to prefix the "@" sign to each # $GL_GET_MEMBERSHIPS_PGM if it is defined
# of them!
push @ret, map { s/^/@/; $_; } split(' ', $ENV{GL_GROUP_LIST}) if $ENV{GL_GROUP_LIST}; 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); return (@ret);
} }

View file

@ -114,10 +114,6 @@ if ($ENV{REQUEST_URI}) {
$user=$ENV{GL_USER}=shift; $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 # logging, timestamp env vars
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------