aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Ruppert <idl0r@gentoo.org>2011-02-15 17:38:31 +0100
committerChristian Ruppert <idl0r@gentoo.org>2011-02-15 17:38:31 +0100
commit231d7fb70ec7acf410fe78e379383c8da021f8dd (patch)
treeaee552def6e3bf2983e3ce394761f11d1875b548
parentAdd missing curly bracket (diff)
parentv1.5.9 (diff)
downloadgitolite-gentoo-231d7fb70ec7acf410fe78e379383c8da021f8dd.tar.gz
gitolite-gentoo-231d7fb70ec7acf410fe78e379383c8da021f8dd.tar.bz2
gitolite-gentoo-231d7fb70ec7acf410fe78e379383c8da021f8dd.zip
Merge branch 'upstream'gitolite-gentoo-1.5.9
Conflicts: conf/example.gitolite.rc src/gl-auth-command
-rw-r--r--conf/example.conf3
-rw-r--r--conf/example.gitolite.rc334
-rwxr-xr-xcontrib/adc/get-rights-and-owner.in-perl41
-rw-r--r--contrib/ldap/README.mkd18
-rw-r--r--contrib/ldap/ldap-query-example.pl80
-rw-r--r--contrib/ldap/ldap-query-example.sh68
-rw-r--r--contrib/ldap/passwd112
-rw-r--r--doc/CHANGELOG22
-rw-r--r--doc/big-config.mkd229
-rw-r--r--doc/delegation.mkd2
-rw-r--r--doc/gitolite.rc.mkd332
-rw-r--r--doc/install-transcript.mkd2
-rw-r--r--doc/overkill.mkd8
-rw-r--r--doc/progit-article.mkd2
-rw-r--r--doc/ssh-troubleshooting.mkd2
-rw-r--r--doc/who-uses-it.mkd5
-rw-r--r--src/gitolite.pm124
-rwxr-xr-xsrc/gl-auth-command14
-rwxr-xr-xsrc/gl-compile-conf164
-rw-r--r--t/out/t01-repo-groups.12
-rw-r--r--t/out/t01-repo-groups.1b2
-rw-r--r--t/out/t01-repo-groups.1bs116
-rw-r--r--t/out/t01-repo-groups.228
-rw-r--r--t/out/t02-user-groups.12
-rw-r--r--t/out/t02-user-groups.1b2
-rw-r--r--t/out/t02-user-groups.1bs79
-rw-r--r--t/out/t02-user-groups.22
-rw-r--r--t/out/t02-user-groups.2bs84
-rw-r--r--t/t01-repo-groups6
-rw-r--r--t/t02-user-groups8
-rw-r--r--t/t59-repo-not-on-disk12
-rwxr-xr-xt/test-driver.sh7
32 files changed, 1407 insertions, 505 deletions
diff --git a/conf/example.conf b/conf/example.conf
index 99ba483..27f99cd 100644
--- a/conf/example.conf
+++ b/conf/example.conf
@@ -162,9 +162,6 @@ repo git
# defined as either permitting the operation you're attempting (`W` or `+`),
# which results in success, or a "deny" (`-`), which results in failure.
# (As before, a fallthrough also results in failure).
-#
-# - do not use `@all` when your config has any deny rules; it won't work as
-# you probably expect it to!
# in the example above, you cannot easily say "anyone can write any tag,
# except version tags can only be written by junio". The following might look
diff --git a/conf/example.gitolite.rc b/conf/example.gitolite.rc
index 211b7cb..6f57994 100644
--- a/conf/example.gitolite.rc
+++ b/conf/example.gitolite.rc
@@ -1,320 +1,86 @@
-# paths and configuration variables for gitolite
+# configuration variables for gitolite
-# please read comments before editing
+# PLEASE READ THE DOCUMENTATION BEFORE EDITING OR ASKING QUESTIONS
+# ( http://github.com/sitaramc/gitolite/blob/pu/doc/gitolite.rc.mkd )
# this file is meant to be pulled into a perl program using "do" or "require".
-
# You do NOT need to know perl to edit the paths; it should be fairly
# self-explanatory and easy to maintain perl syntax :-)
-# --------------------------------------
-# Do not change the next two lines unless you know what you're doing
-# $GL_PACKAGE_CONF = "";
-# $GL_PACKAGE_HOOKS = "";
-
-# --------------------------------------
-# MIRRORING SUPPORT
-
-# $GL_SLAVE_MODE = 0;
-# $ENV{GL_SLAVES} = 'gitolite@server2 gitolite@server3';
-# PLEASE USE SINGLE QUOTES ABOVE, NOT DOUBLE QUOTES
-
-# see doc/mirroring.mkd for details
-
-# --------------------------------------
-
-# this is where the repos go. If you provide a relative path (not starting
-# with "/"), it's relative to your $HOME. You may want to put in something
-# like "/bigdisk" or whatever if your $HOME is too small for the repos, for
-# example
-
-$REPO_BASE="repositories";
-
-# the default umask for repositories is 0077; change this if you run stuff
-# like gitweb and find it can't read the repos. Please note the syntax; the
-# leading 0 is required
-
-$REPO_UMASK = 0077; # gets you 'rwx------'
-# $REPO_UMASK = 0027; # gets you 'rwxr-x---'
-# $REPO_UMASK = 0022; # gets you 'rwxr-xr-x'
-
-# part of the setup of gitweb is a variable called $projects_list (please see
-# gitweb documentation for more on this). Set this to the same value:
-
-$PROJECTS_LIST = $ENV{HOME} . "/projects.list";
-
-# giving access to @all users (as in "R = @all") in the config normally does
-# *not* include the special users "gitweb" and "daemon". If you want @all to
-# include these two users, set this variable:
-
-# $GL_ALL_INCLUDES_SPECIAL = 0;
-
-# --------------------------------------
-
-# I see no reason anyone may want to change the gitolite admin directory, but
-# feel free to do so. However, please note that it *must* be an *absolute*
-# path (i.e., starting with a "/" character)
-
-# gitolite admin directory, files, etc
-
+# ------------------------------------------------------------------------------
+# VARIABLES THAT SHOULD NOT BE TOUCHED AT ALL. EVER.
+# ------------------------------------------------------------------------------
$GL_ADMINDIR=$ENV{HOME} . "/.gitolite";
-
-# --------------------------------------
-
-# templates for location of the log files and format of their names
-
-# I prefer this template (note the %y and %m placeholders)
-# it produces files like `~/.gitolite/logs/gitolite-2009-09.log`
-
-$GL_LOGT="$GL_ADMINDIR/logs/gitolite-%y-%m.log";
-
-# other choices are below, or you can make your own -- but PLEASE MAKE SURE
-# the directory exists and is writable; gitolite won't do that for you (unless
-# it is the default, which is "$GL_ADMINDIR/logs")
-
-# $GL_LOGT="$GL_ADMINDIR/logs/gitolite-%y-%m-%d.log";
-# $GL_LOGT="$GL_ADMINDIR/logs/gitolite-%y.log";
-
-# --------------------------------------
-
-# location of the performance log files
-
-# uncomment and set this variable if you want performance logging
-#
-# perf log files are different from access log files; they store different
-# information, are not meant to be as long-lived, and so on
-
-# $GL_PERFLOGT="$GL_ADMINDIR/logs/perf-gitolite-%y-%m.log";
-
-# --------------------------------------
-
-# Please DO NOT change these three paths
-
$GL_CONF="$GL_ADMINDIR/conf/gitolite.conf";
$GL_KEYDIR="$GL_ADMINDIR/keydir";
$GL_CONF_COMPILED="$GL_ADMINDIR/conf/gitolite.conf-compiled.pm";
+# DO NOT CHANGE THE NEXT TWO LINES UNLESS YOU REALLY KNOW WHAT YOU'RE DOING.
+# These variables are set automatically by the install method you choose.
+# $GL_PACKAGE_CONF = "";
+# $GL_PACKAGE_HOOKS = "";
-# --------------------------------------
-
-# if git on your server is on a standard path (that is
-# ssh git@server git --version
-# works), leave this setting as is. Otherwise, choose one of the
-# alternatives, or write your own
-
-$GIT_PATH="";
-# $GIT_PATH="/opt/bin/";
-
-# --------------------------------------
-
-# ----------------------------------------------------------------------
-# BIG CONFIG SETTINGS
-
-# Please read doc/big-config.mkd for details
+# ------------------------------------------------------------------------------
+# most often used/changed variables
+# ------------------------------------------------------------------------------
+$GL_WILDREPOS = 0;
+$PROJECTS_LIST = $ENV{HOME} . "/projects.list";
+$REPO_UMASK = 0077;
+# ------------------------------------------------------------------------------
+# variables with an efficiency impact
+# ------------------------------------------------------------------------------
$GL_BIG_CONFIG = 0;
$GL_NO_DAEMON_NO_GITWEB = 0;
-$GL_NO_CREATE_REPOS = 0;
-$GL_NO_SETUP_AUTHKEYS = 0;
-
-# ----------------------------------------------------------------------
-# SECURITY SENSITIVE SETTINGS
-#
-# Settings below this point may have security implications. That
-# usually means that I have not thought hard enough about all the
-# possible ways to crack security if these settings are enabled.
-
-# Please see details on each setting for specifics, if any.
-# ----------------------------------------------------------------------
-
# Define which metadata variables shall be exported to the gitolite environment.
# Those variables can be used in hooks, e.g. for cia.vc
# A pubkey file might contain one or more of those variable.
# They can be defined by e.g:"# git-username: idl0r"
# Each '-' (dash) will be replaced by an '_' (underscore).
-@GL_METADATA = ( "git-username", "git-email", "git-realname", "git-realname-ascii", "cia-vc-username" );
-@GL_METADATA_REQUIRED = ( "git-username", "git-email", "git-realname" );
-
-# --------------------------------------
-# ALLOW REPO ADMIN TO SET GITCONFIG KEYS
-#
-# 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.
-#
-# You have 3 choices. By default $GL_GITCONFIG_KEYS is left empty, which
-# completely disables this feature (meaning you cannot set git configs from
-# the repo config).
-
+#@GL_METADATA = ( "git-username", "git-email", "git-realname", "git-realname-ascii", "cia-vc-username" );
+#@GL_METADATA_REQUIRED = ( "git-username", "git-email", "git-realname" );
+
+# ------------------------------------------------------------------------------
+# VARIABLES WITH A SECURITY IMPACT. READ DOC WELL BEFORE CHANGING THESE.
+# http://github.com/sitaramc/gitolite/blob/pu/doc/gitolite.rc.mkd#_variables_with_a_security_impact
+# ------------------------------------------------------------------------------
+# $GL_ALL_READ_ALL = 0;
+$GIT_PATH="";
$GL_GITCONFIG_KEYS = "";
-
-# The second choice is to give it a space separated list of settings you
-# consider safe. (These are actually treated as a set of regular expression
-# patterns, and any one of them must match). For example:
-# $GL_GITCONFIG_KEYS = "core\.logAllRefUpdates core\..*compression";
-# allows repo admins to set one of those 3 config keys (yes, that second
-# pattern matches two settings from "man git-config", if you look)
-#
-# The third choice (which you may have guessed already if you're familiar with
-# regular expressions) is to allow anything and everything:
-# $GL_GITCONFIG_KEYS = ".*";
-
-# NOTE that due to some quoting and interpolation issues I have not been able
-# to look at, a literal "." needs to be specified in this string as \\. (two
-# backslashes and a dot). So this is how you'd allow any keys in the "foo"
-# category:
-# $GL_GITCONFIG_KEYS = "foo\\..*";
-
-# --------------------------------------
-# ALLOW GITCONFIG KEYS EVEN FOR WILD REPOS
-#
-# This is an efficiency issue more than a security issue, since this requires
-# trawling through all of $REPO_BASE looking for stuff :)
-
# $GL_GITCONFIG_WILD = 0;
-
-# --------------------------------------
-# EXTERNAL COMMAND HELPER -- HTPASSWD
-
-# security note: runs an external command (htpasswd) with specific arguments,
-# including a user-chosen "password".
-
-# if you want to enable the "htpasswd" command, give this the absolute path to
-# whatever file apache (etc) expect to find the passwords in.
-
+$GL_NO_CREATE_REPOS = 0;
+$GL_NO_SETUP_AUTHKEYS = 0;
+# $GL_WILDREPOS_DEFPERMS = 'R @all';
$HTPASSWD_FILE = "";
-
-# Look in doc/3 ("easier to link gitweb authorisation with gitolite" section)
-# for more details on using this feature.
-
-# --------------------------------------
-# EXTERNAL COMMAND HELPER -- RSYNC
-
-# security note: runs an external command (rsync) with specific arguments, all
-# presumably filled in correctly by the client-side rsync.
-
-# base path of all the files that are accessible via rsync. Must be an
-# absolute path. Leave it undefined or set to the empty string to disable the
-# rsync helper.
-
$RSYNC_BASE = "";
-
-# $RSYNC_BASE = "/home/git/up-down";
-# $RSYNC_BASE = "/tmp/up-down";
-
-# --------------------------------------
-# EXTERNAL COMMAND HELPER -- SVNSERVE
-
-# security note: runs an external command (svnserve) with specific arguments,
-# as specified below. %u is substituted with the username.
-
-# This setting allows launching svnserve when requested by the ssh client.
-# This allows using the same SSH setup (hostname/username/public key) for both
-# SVN and git access. Leave it undefined or set to the empty string to disable
-# svnserve access.
-
$SVNSERVE = "";
-# $SVNSERVE = "/usr/bin/svnserve -r /var/svn/ -t --tunnel-user=%u";
-
-# --------------------------------------
-# ALLOW REPO CONFIG TO USE WILDCARDS
-
-# security note: this used to in a separate "wildrepos" branch. You can
-# create repositories based on wild cards, give "ownership" to the specific
-# user who created it, allow him/her to hand out R and RW permissions to other
-# users to collaborate, etc. This is powerful stuff, and I've made it as
-# secure as I can, but it hasn't had the kind of rigorous line-by-line
-# analysis that the old "master" branch had.
-
-# This has now been rolled into master, with all the functionality gated by
-# this variable. Set this to 1 if you want to enable the wildrepos features.
-# Please see doc/wildcard-repositories.mkd for details.
-
-$GL_WILDREPOS = 0;
-
-# --------------------------------------
-# DEFAULT WILDCARD PERMISSIONS
-
-# If set, this value will be used as the default user-level permission rule of
-# new wildcard repositories. The user can change this value with the setperms command
-# as desired after repository creation; it is only a default. Note that @all can be
-# used here but is special; no other groups can be used in user-level permissions.
-
-# $GL_WILDREPOS_DEFPERMS = 'R @all';
-
-# --------------------------------------
-# WILDREPOS PERMS CATEGORIES
-
-# Originally, we only allowed "R" and "RW" in the setperms command. Now we
-# allow the admin to define other categories as she wishes (example: MANAGERS,
-# TESTERS, etc).
-
-# This variable is a space-sep list of the allowed categories.
-
-# PLEASE, *PLEASE*, read the section in doc/wildcard-repositories.mkd for
-# caveats and warnings. This is a VERY powerful feature and if you're not
-# careful you could mess up the ACLs nicely.
-
-# this is the internal default if you don't set it (like if you didn't update
-# your ~/.gitolite.rc with new variables when you upgraded gitolite):
-$GL_WILDREPOS_PERM_CATS = "READERS WRITERS";
-
-# you can use your own categories in addition to the standard ones; I suggest
-# you include READERS and WRITERS for backward compat though:
-# $GL_WILDREPOS_PERM_CATS = "READERS WRITERS MANAGERS";
-# $GL_WILDREPOS_PERM_CATS = "READERS WRITERS MANAGERS TESTERS";
-
-# --------------------------------------
-# HOOK CHAINING
-
-# by default, the update hook in every repo chains to "update.secondary".
-# Similarly, the post-update hook in the admin repo chains to
-# "post-update.secondary". If you're fine with the defaults, there's no need
-# to do anything here. However, if you want to use different names or paths,
-# change these variables
-
# $UPDATE_CHAINS_TO = "hooks/update.secondary";
# $ADMIN_POST_UPDATE_CHAINS_TO = "hooks/post-update.secondary";
-
-# --------------------------------------
-# ADMIN DEFINED COMMANDS
-
-# WARNING: Use this feature only if (a) you really really know what you're
-# doing or (b) you really don't care too much about security. Please read
-# doc/admin-defined-commands.mkd for details.
-
# $GL_ADC_PATH = "";
+# $GL_GET_MEMBERSHIPS_PGM = "/usr/local/bin/expand-ldap-user-to-groups"
-# --------------------------------------
-# SITE-SPECIFIC INFORMATION
-
-# Some installations would like to give their users customised information
-# (like a link to their own websites, for example) so that each end user does
-# not have to grok all the gitolite documentation.
-
-# If this variable is defined, the "info" command will print it at the end of
-# the listing.
+# ------------------------------------------------------------------------------
+# less used/changed variables
+# ------------------------------------------------------------------------------
+# $GL_ALL_INCLUDES_SPECIAL = 0;
+# $GL_SLAVE_MODE = 0;
+# $ENV{GL_SLAVES} = 'gitolite@server2 gitolite@server3';
+# PLEASE USE SINGLE QUOTES ABOVE, NOT DOUBLE QUOTES
+$GL_WILDREPOS_PERM_CATS = "READERS WRITERS";
-# $GL_SITE_INFO = "";
+# ------------------------------------------------------------------------------
+# rarely changed variables
+# ------------------------------------------------------------------------------
+$GL_LOGT="$GL_ADMINDIR/logs/gitolite-%y-%m.log";
+# $GL_PERFLOGT="$GL_ADMINDIR/logs/perf-gitolite-%y-%m.log";
# $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"
+# ------------------------------------------------------------------------------
+# variables that should NOT be changed after the install step completes
+# ------------------------------------------------------------------------------
+$REPO_BASE="repositories";
-# --------------------------------------
+# ------------------------------------------------------------------------------
# per perl rules, this should be the last line in such a file:
1;
diff --git a/contrib/adc/get-rights-and-owner.in-perl b/contrib/adc/get-rights-and-owner.in-perl
new file mode 100755
index 0000000..d848cfb
--- /dev/null
+++ b/contrib/adc/get-rights-and-owner.in-perl
@@ -0,0 +1,41 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+unshift @INC, $ENV{GL_BINDIR};
+require gitolite or die "parse gitolite.pm failed\n";
+
+# get the repo name
+my $repo = shift;
+$repo =~ s/\.git$//;
+# IMPORTANT NOTE: to do any of this inside a hook, you should just use
+# $ENV{GL_REPO}, since it's guaranteed to be set to the right value
+
+
+
+# to do a "level 1" check (repo level -- not branch level), do this:
+my ($perm, $creator) = &check_access($repo);
+# you can pass in any repo name you wish instead of the active repo
+
+# the first return value looks like one of these, so you can just check for
+# the presence of "R" or "W" and be done:
+# _____R___W_
+# _____R_____
+# ___________
+
+# The second value is "<gitolite>" for a normal repo, an actual username for
+# a wildrepo, or "<notfound>" for a non-existent repo.
+
+
+
+# to do a "level 2" check (branches), do something like this
+my $ret = &check_access($repo, 'refs/heads/foo', 'W', 1);
+# the 2nd argument must be a *full* refname (i.e., not "master", but
+# "refs/heads/master"). The 3rd argument is one of W, +, C, or D. The 4th
+# argument should be any non-false perl value, like 1.
+
+# the return value may look like this:
+# refs/.*
+# or perhaps this, if you were denied
+# DENIED by fallthru
diff --git a/contrib/ldap/README.mkd b/contrib/ldap/README.mkd
new file mode 100644
index 0000000..a7dc764
--- /dev/null
+++ b/contrib/ldap/README.mkd
@@ -0,0 +1,18 @@
+These programs were contributed by the Nokia MeeGo folks.
+
+The first 2 are perl and shell verisions of programs meant to be used as
+`$GL_GET_MEMBERSHIPS_PGM` (see [this][ldap] for more).
+
+
+ * ldap-query-example.pl
+ * ldap-query-example.sh
+
+The third program is meant to be installed as an adc (admin-defined command,
+see [here][adc]), and helps users change their LDAP passwords.
+
+ * passwd
+
+Enjoy!
+
+[ldap]: http://github.com/sitaramc/gitolite/blob/pu/doc/big-config.mkd#_storing_usergroup_information_outside_gitolite_like_in_LDAP_
+[adc]: http://github.com/sitaramc/gitolite/blob/pu/doc/admin-defined-commands.mkd
diff --git a/contrib/ldap/ldap-query-example.pl b/contrib/ldap/ldap-query-example.pl
new file mode 100644
index 0000000..663e318
--- /dev/null
+++ b/contrib/ldap/ldap-query-example.pl
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 2010 Nokia Corporation
+#
+# This code is licensed to you under MIT-style license. License text for that
+# MIT-style license is as follows:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ldap-query.pl <arg1>
+#
+# this script is used to perform ldap querys by giving one argument:
+# - <arg1> the user UID for ldap search query
+#
+# NOTICE: This script requires libnet-ldap-perl package to be installed
+# to the system.
+#
+
+use Net::LDAP;
+
+# Script requires user UID as the only parameter
+if ( $ARGV[0] eq '' || $ARGV[1] ne '' )
+{
+ print "ldap-query.pl requires one argument, user's uid\n";
+ exit 1;
+}
+$user = $ARGV[0];
+
+# Create communication structure for LDAP connection
+$ldap = Net::LDAP->new(
+ 'localhost',
+ port => 389,
+ debug => 0,
+ timeout => 120,
+ version => 3 ) or die "$@";
+
+# Bind to LDAP with proper user
+$ldapret = $ldap->bind( 'cn=administrator,o=company',
+ password => '5ecretpa55w0rd' );
+die "$ldapret->code" if $ldapret->code;
+
+# Create filter for LDAP query
+my $filter = '(&'.
+ '(objectClass=groupAttributeObjectClassName)'.
+ "(uid=$user)".
+ ')';
+
+# Execute the actual LDAP search to get groups for the given UID
+$ldapret = $ldap->search( base => 'ou=users,ou=department,o=company',
+ scope => 'subtree',
+ filter => $filter );
+
+# Parse search result to get actual group names
+my $default_group = '';
+my $extra_groups = '';
+
+foreach my $entry ( $ldapret->entries ) {
+
+ $default_group = $entry->get_value( 'defaultGroupAttributeName' ) . ' ' . "$default_group";
+ $extra_groups = $entry->get_value( 'extraGroupsAttributeName' ) . ' ' . "$extra_groups";
+}
+
+# Return group names for given user UID
+print "$default_group" . "$extra_groups";
diff --git a/contrib/ldap/ldap-query-example.sh b/contrib/ldap/ldap-query-example.sh
new file mode 100644
index 0000000..43d13e4
--- /dev/null
+++ b/contrib/ldap/ldap-query-example.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Nokia Corporation
+#
+# This code is licensed to you under MIT-style license. License text for that
+# MIT-style license is as follows:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ldap-query.sh <arg1>
+#
+# this script is used to perform ldap querys by giving one argument:
+# - <arg1> the user UID for ldap search query
+#
+# NOTICE: This script requires ldap-utils and sed to be installed to the system.
+#
+
+# Script requires user UID as the only parameter
+#
+if [ $# -ne 1 ]
+then
+ echo "ldap-query.sh requires one argument, user's uid"
+ exit 1
+fi
+uid_param="${1}"
+
+# Set needed LDAP search tool options for the query
+ldap_host="localhost"
+ldap_binddn="cn=administrator,o=company"
+ldap_bindpw="5ecretpa55w0rd"
+ldap_searchbase="ou=users,ou=department,o=company"
+ldap_scope="subtree"
+
+# Construct the command line base with needed options for the LDAP query
+ldap_options="-h ${ldap_host} -x -D ${ldap_binddn} -w ${ldap_bindpw} -b ${ldap_searchbase} -s ${ldap_scope}"
+
+# Construct the search filter for the LDAP query for the given UID
+ldap_filter="(&(objectClass=groupAttributeObjectClassName)(uid=${uid_param}))"
+
+# Construct return attribute list for LDAP query result
+attr1="defaultGroupAttributeName"
+attr2="extraGroupsAttributeName"
+ldap_attr="${attr1} ${attr2}"
+
+# Execute the actual LDAP search to get groups for the given UID
+ldap_result=$(ldapsearch ${ldap_options} -LLL ${ldap_filter} ${ldap_attr})
+
+# Edit search result to get space separated list of group names
+ldap_result=$(echo ${ldap_result} | sed -e "s/.* ${attr1}://" -e "s/ ${attr2}://")
+
+# Return group names for given user UID
+echo ${ldap_result}
diff --git a/contrib/ldap/passwd b/contrib/ldap/passwd
new file mode 100644
index 0000000..f555f65
--- /dev/null
+++ b/contrib/ldap/passwd
@@ -0,0 +1,112 @@
+#!/usr/bin/perl
+
+use Net::LDAP;
+use Term::ReadPassword;
+use Digest::SHA1;
+use MIME::Base64;
+use Data::UUID;
+use Crypt::Cracklib;
+
+my $PASSWD_MIN_LEN = 8;
+my $password;
+
+# parse RC file
+# $ENV{GL_RC} = "/home/gitolite/.gitolite.rc";
+die "parse $ENV{GL_RC} failed: " . ($! or $@) unless do $ENV{GL_RC};
+
+# These come from .gitolite.rc file
+our ($GL_LDAP_HOST, $GL_LDAP_BIND_DN, $GL_LDAP_BIND_PASSWORD, $GL_LDAP_USER_DN);
+
+$Term::ReadPassword::ALLOW_STDIN = 1;
+
+# NOTICE: For some reason Perl fails to disable terminal echo
+# so following warning about ECHO must be given to the user
+
+# Warn about password echo because of bugs in Perl ReadPasword
+print "\nNOTE THAT THE PASSWORD WILL BE ECHOED TO THE SCREEN!\n" .
+"Please make sure no one is shoulder-surfing, and make sure\n" .
+"you clear your screen and scrollback history after you are done\n" .
+"(or close your terminal session).\n\n";
+
+print "Please type in your new password at the prompt.\n\n" .
+"Following special keys are available while typing:\n" .
+" <BackSpace> key to remove the last character\n" .
+" <Ctrl-U> to remove all characters\n" .
+" <Ctrl-C> to terminate password change operation\n" .
+" <Enter> to end password typing\n";
+
+while ( 1 ) {
+
+ print "\n"; # Start reading with new line
+ $password = read_password("Enter new password: ", 0, 1);
+
+ # Check the validity of new password
+ if ( length( $password ) >= $PASSWD_MIN_LEN # require minimum length
+ && $password =~ /([\x20-\x7E])/ # require printable characters
+ && $password =~ /[a-z]/ # require lower case letter
+ && $password =~ /[A-Z]/ # require upper case letter
+ && $password =~ /[0-9]/ # require number
+ && check( $password ) ) # require other than dictionary words
+ {
+ # Re-enter new password to check possible typos
+ if ( $password ne read_password("Enter password again: ") ) {
+
+ print "Passwords do not match!\n";
+ redo;
+ } else {
+
+ last; # Password is valid and there are no typos, so break out
+ }
+ } else { # Given password is not valid
+
+ print "Password must contain at least $PASSWD_MIN_LEN characters and numbers,\n" .
+ "must have both upper and lower case characters,\n" .
+ "can have special characters like !,",#,...\n" .
+ "but cannot be any valid dictionary word.\n";
+ redo;
+ }
+}
+
+# Create hash from the password to be stored to the LDAP
+my $ctx = Digest::SHA1->new();
+my $ug = new Data::UUID;
+my $salt = $ug->create_b64();
+$ctx->add( $password );
+$ctx->add( $salt );
+$password = '{SSHA}' . encode_base64( $ctx->digest . $salt, '' );
+
+# Create communication structure for LDAP connection
+my $ldap = Net::LDAP->new( $GL_LDAP_HOST ) or die "$@";
+my $r = $ldap->start_tls( verify => 'none',
+ sslversion => 'tlsv1' );
+if ( $r->code ) {
+ print "Password handling failed with $r->code return code!\n";
+ log_it( "Password change, LDAP connection failed for $ENV{GL_USER}" );
+ exit 1;
+}
+
+# Bind to LDAP with proper user
+$r = $ldap->bind( $GL_LDAP_BIND_DN,
+ password => $GL_LDAP_BIND_PASSWORD );
+if ( $r->code ) {
+ print "Password update failed with $r->code return code!\n";
+ log_it( "Password change, LDAP bind failed for $ENV{GL_USER}" );
+ exit 1;
+}
+
+# Update new password to the LDAP
+$r = $ldap->modify( "uid=$ENV{GL_USER},
+ $GL_LDAP_USER_DN",
+ replace => { 'userPassword', $password } );
+
+if ( $r->code ) {
+ print "Password change failed!\n" .
+ "Please contact administrator to change password.\n";
+# log_it( "Password change, LDAP modify failed for $ENV{GL_USER}" );
+} else {
+ print "Password changed succesfully.\n";
+# log_it( "Password change, LDAP modify done for $ENV{GL_USER}" );
+}
+
+$r = $ldap->unbind();
+
diff --git a/doc/CHANGELOG b/doc/CHANGELOG
index 7062be0..9dde36b 100644
--- a/doc/CHANGELOG
+++ b/doc/CHANGELOG
@@ -2,6 +2,28 @@ Major changes to gitolite, master branch only, most recent first, no dates but
the tags can help you position stuff approximately
[NYD = not yet documented due to lack of time...]
+ - v1.5.9
+
+ - Nokia MeeGo team contributed ldap scripts
+
+ - large configs should now be twice as fast (except when gl-perms exists)
+ due to my finding and eliminating a wasted parse_acl
+
+ - major change: split the config file when in big-config mode
+ (includes a data format change)
+
+ - GL_ALL_READ_ALL to make things much, (MUCH!) faster for sites where all
+ can read all repos (like Fedora)
+
+ - rc file revamp -- was getting too big and unwieldy; now the documentation
+ is in a new file instead of inline
+
+ - allow gitolite to be used even when users have real IDs (thus $HOME is not
+ valid to find the rc file); allow /etc/gitolite/gitolite.rc then
+
+ - BIG one for adc writers -- full blown access checks (ref level) can be
+ done from an ADC now (though it has to be in perl, not shell)!
+
- allow full access checks from perl (shell can only do level 1 checks);
useful in hooks or ADCs
diff --git a/doc/big-config.mkd b/doc/big-config.mkd
index 440288b..69b5e46 100644
--- a/doc/big-config.mkd
+++ b/doc/big-config.mkd
@@ -4,6 +4,8 @@ In this document:
* <a href="#_when_why_do_we_need_it_">when/why do we need it?</a>
* <a href="#_how_do_we_use_it_">how do we use it?</a>
+ * <a href="#_access_rules_for_groups">access rules for groups</a>
+ * <a href="#_access_rules_for_individual_repos_split_config_">access rules for individual repos (split config)</a>
* <a href="#_other_optimisations">other optimisations</a>
* <a href="#_disabling_various_defaults">disabling various defaults</a>
* <a href="#_optimising_the_authkeys_file">optimising the authkeys file</a>
@@ -18,10 +20,10 @@ In this document:
### when/why do we need it?
A "big config" is anything that has a few thousand users and a few thousand
-repos, organised into groups that are much smaller in number (like maybe a few
-hundreds of repogroups and a few dozens of usergroups).
+repos, resulting in a very large 'compiled' config file.
-So let's say you have
+To understand the problem, consider what happens if you have something like
+this in your gitolite conf file:
@wbr = lynx firefox
@devs = alice bob
@@ -30,15 +32,15 @@ So let's say you have
RW+ next = @devs
RW master = @devs
-Gitolite internally translates this to
+Without the 'big config' setting, gitolite internally translates this to:
repo lynx firefox
RW+ next = alice bob
RW master = alice bob
-Not just that -- it now generates the actual config rules once for each
-user-repo-ref combination (there are 8 combinations above; the compiled config
-file looks partly like this:
+and then generates the actual config rules once for each user-repo-ref
+combination (there are 8 combinations above); the compiled config file looks
+somewhat like this:
%repos = (
'firefox' => {
@@ -51,20 +53,28 @@ file looks partly like this:
'bob' => 1
},
'alice' => [
- {
- 'refs/heads/next' => 'RW+'
- },
- {
- 'refs/heads/master' => 'RW'
- }
+ [
+ 0,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 4,
+ 'refs/heads/master',
+ 'RW'
+ ]
],
'bob' => [
- {
- 'refs/heads/next' => 'RW+'
- },
- {
- 'refs/heads/master' => 'RW'
- }
+ [
+ 1,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 5,
+ 'refs/heads/master',
+ 'RW'
+ ]
]
},
'lynx' => {
@@ -77,54 +87,73 @@ file looks partly like this:
'bob' => 1
},
'alice' => [
- {
- 'refs/heads/next' => 'RW+'
- },
- {
- 'refs/heads/master' => 'RW'
- }
+ [
+ 2,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 6,
+ 'refs/heads/master',
+ 'RW'
+ ]
],
'bob' => [
- {
- 'refs/heads/next' => 'RW+'
- },
- {
- 'refs/heads/master' => 'RW'
- }
+ [
+ 3,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 7,
+ 'refs/heads/master',
+ 'RW'
+ ]
]
}
);
Phew!
-You can imagine what that does when you have 10,000 users and 10,000 repos.
-Let's just say it's not pretty :)
+Of course, the output is the same whether you used groups (like `@wbr` and
+`@devs` in the example above) or listed the repos directly on the 'repo'
+lines.
+
+Anyway, you can imagine what that does when you have 10,000 users and 10,000
+repos. Let's just say it's not pretty :)
<a name="_how_do_we_use_it_"></a>
### how do we use it?
-Now, if you had all those 10,000 users and repos explicitly listed (no
-groups), then there is no help. But if, like the above example, you had
-groups like we used above, there is hope.
-
Just set
$GL_BIG_CONFIG = 1;
in the `~/.gitolite.rc` file on the server (see next section for more
-variables). When you do that, and push this configuration, the compiled file
-looks like this:
+variables). When you do that, and push this configuration, one of two things
+happens.
+
+<a name="_access_rules_for_groups"></a>
+
+#### access rules for groups
+
+If you used group names in the 'repo' lines (as in `repo @wbr`), then the
+compiled config looks like this:
%repos = (
'@wbr' => {
'@devs' => [
- {
- 'refs/heads/next' => 'RW+'
- },
- {
- 'refs/heads/master' => 'RW'
- }
+ [
+ 0,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 1,
+ 'refs/heads/master',
+ 'RW'
+ ]
],
'R' => {
'@devs' => 1
@@ -132,7 +161,7 @@ looks like this:
'W' => {
'@devs' => 1
}
- },
+ }
);
%groups = (
'@devs' => {
@@ -148,6 +177,62 @@ looks like this:
That's a lot smaller, and allows orders of magintude more repos and groups to
be supported.
+<a name="_access_rules_for_individual_repos_split_config_"></a>
+
+#### access rules for individual repos (split config)
+
+If, on the other hand, you had the repos listed individually, (as in `repo
+lynx firefox`), then the main config file would now look like this:
+
+ %repos = ();
+ %split_conf = (
+ 'firefox' => 1,
+ 'lynx' => 1
+ );
+
+And each individual repo's configuration would go its own directory. For
+instance, `~/repositories/lynx.git/gl-conf` would look like this:
+
+ %one_repo = (
+ 'lynx' => {
+ 'R' => {
+ 'alice' => 1,
+ 'bob' => 1
+ },
+ 'W' => {
+ 'alice' => 1,
+ 'bob' => 1
+ },
+ 'alice' => [
+ [
+ 0,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 4,
+ 'refs/heads/master',
+ 'RW'
+ ]
+ ],
+ 'bob' => [
+ [
+ 1,
+ 'refs/heads/next',
+ 'RW+'
+ ],
+ [
+ 5,
+ 'refs/heads/master',
+ 'RW'
+ ]
+ ]
+ }
+ );
+
+That does not reduce the overall size of the repo config (because you did not
+group the repos), but the main repo config is now even smaller!
+
<a name="_other_optimisations"></a>
### other optimisations
@@ -169,22 +254,18 @@ if you *do* have a large number of repositories, and do *not* use gitolite's
support for gitweb or git-daemon access (see "[easier to specify gitweb
description and gitweb/daemon access][gwd]" for details). This will save a
lot of time when you push the gitolite-admin repo with changes. This variable
-also control whether "git config" lines (such as `config hooks.emailprefix =
+also controls whether "git config" lines (such as `config hooks.emailprefix =
"[gitolite]"`) will be processed or not.
-Setting this is relatively harmless to a normal installation, unlike the next
-two variables :-) `GL_NO_CREATE_REPOS` and `GL_NO_SETUP_AUTHKEYS` are meant
-for installations where some backend system already exists that does all the
-actual repo creation, and all the authentication setup (ssh auth keys),
-respectively.
+You should be a lot more careful with `GL_NO_CREATE_REPOS` and
+`GL_NO_SETUP_AUTHKEYS`. These are meant for installations where some backend
+system already exists that does all the actual repo creation, (including
+setting up the proper hooks -- very important for access control), and all the
+authentication setup (ssh auth keys), respectively.
Summary: Please **leave those two variables alone** unless you're initials are
"JK" ;-)
-Also note that using all 3 of the `GL_NO_*` variables will result in
-*everything* after the config compile being skipped. In other words, gitolite
-is being used **only** for its access control language.
-
<a name="_optimising_the_authkeys_file"></a>
#### optimising the authkeys file
@@ -228,15 +309,29 @@ this (note the clever date command that always gets you last months log file!)
### what are the downsides?
-There is one minor issue.
+There are some downsides. The first one applies in all cases:
+
+ * If you use the delegation feature, you can no longer define or extend
+ @groups in a fragment, for security reasons. It will also not let you use
+ any group other than the @fragname itself (specifically, groups which
+ contained a 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!)
+
+The following apply if individual ("split") conf files are written, which in
+turn only happens if you used repo names instead of group names on the `repo`
+lines:
-If you use the delegation feature, you can no longer define or extend
-@groups in a fragment, for security reasons. It will also not let you use any
-group other than the @fragname itself (specifically, groups which contained a
-subset of the allowed @fragname, which would work normally, do not work now).
+ * the compile (gitolite-admin push) is now slower, because it potentially
+ has to write a few thousand small files instead of one large one. Since
+ the compile should be relatively infrequent compared to developer access,
+ this is ok -- the main config file is parsed much faster now, so every hit
+ to the server will benefit.
-(If you didn't understand all that, you're probably not using delegation, so
-feel free to ignore it!)
+ * we can no longer distinguish 'repo not found on disk' from 'you dont have
+ access'. They both now look like 'you dont have access'.
<a name="_storing_usergroup_information_outside_gitolite_like_in_LDAP_"></a>
@@ -298,10 +393,10 @@ path to this program, set `$GL_BIG_CONFIG` to 1, and that will be that.
### implementation notes
-To understand how big-config works, we'll first look at how it works without
-this setting. Think back to the example at the top, and assume 'alice' is
-accessing the 'lynx' repo. The various rights are governed by the following
-hash elements:
+To understand how big-config works (at least when you're using grouped repos),
+we'll first look at how it works without this setting. Think back to the
+example at the top, and assume 'alice' is accessing the 'lynx' repo. The
+various rights are governed by the following hash elements:
# for the first level checks
$repos{'lynx'}{'R'}{'alice'} = 1
diff --git a/doc/delegation.mkd b/doc/delegation.mkd
index 9fe4293..b450403 100644
--- a/doc/delegation.mkd
+++ b/doc/delegation.mkd
@@ -71,7 +71,7 @@ in charge of malware ;-)
[abe]: http://en.wikipedia.org/wiki/Alice_and_Bob#List_of_characters
-You do this by adding branches to the `gitolite-admin` repo:
+You do this by adding files with specific names to the `gitolite-admin` repo:
# the admin repo access was probably like this to start with:
repo gitolite-admin
diff --git a/doc/gitolite.rc.mkd b/doc/gitolite.rc.mkd
new file mode 100644
index 0000000..e354ff0
--- /dev/null
+++ b/doc/gitolite.rc.mkd
@@ -0,0 +1,332 @@
+# configuration variables for gitolite
+
+This is the documentation for the contents of the "rc" file
+(`$HOME/.gitolite.rc`) on the server. Until now this documentation was
+inline, within the rc file itself, but it has grown too large, too unwieldy,
+and too difficult to grok for people new to gitolite.
+
+The documentation follows approximately the same order as the sample variables
+in the (now reorganised) example "rc" file.
+
+In this document:
+
+ * <a href="#_variables_that_should_not_be_touched_at_all">variables that should not be touched at all</a>
+ * <a href="#_most_often_used_changed_variables">most often used/changed variables</a>
+ * <a href="#_variables_with_an_efficiency_impact">variables with an efficiency impact</a>
+ * <a href="#_variables_with_a_security_impact">variables with a security impact</a>
+ * <a href="#_less_used_changed_variables">less used/changed variables</a>
+ * <a href="#_rarely_changed_variables">rarely changed variables</a>
+
+[Note: in perl, there is no actual boolean. The undefined value, the number
+'0', and the empty string, are all 'false'. Everything else is 'true'. It is
+thus common to use just 0/1 for false/true].
+
+<a name="_variables_that_should_not_be_touched_at_all"></a>
+
+### variables that should not be touched at all
+
+The first section does not need too much elaboration. Let's just say bad
+things happen if you change them.
+
+<a name="_most_often_used_changed_variables"></a>
+
+### most often used/changed variables
+
+ * `$GL_WILDREPOS`, boolean, default 0
+
+ Setting this variable lets your users create repositories based on wild
+ cards, hand out R and RW permissions to other users to collaborate, etc.
+
+ See [doc/wildcard-repositories.mkd][wild] for lots of info on this.
+
+ * `$PROJECTS_LIST`, filename, default `~/projects.list`
+
+ This is for gitweb users only. Gitweb setup has a variable called
+ `$projects_list` (please see gitweb docs for more on this). Set this to
+ the same value as that one.
+
+ * `$REPO_UMASK`, octal, default `0077`
+
+ The default UMASK that gitolite uses makes all the repos and their
+ contents have `rwx------` permissions. People who want to run gitweb
+ realise that this will not do. The correct way to deal with this is to
+ change this variable to `0027` (which gets you `rwxr-x---`), then add the
+ apache or httpd user running the webserver as a member of the 'gitolite'
+ group.
+
+ Please note the syntax; the leading 0 is required. If you change it
+ *after* the install is complete, you'll have to do some chmod's also to
+ adjust permissions of files and directories that have already been
+ created.
+
+<a name="_variables_with_an_efficiency_impact"></a>
+
+### variables with an efficiency impact
+
+ * `$GL_BIG_CONFIG`, boolean, default 0
+
+ This is the most common setting for efficiency in handling large repo/user
+ groups. This is a very powerful setting; please read
+ [doc/big-config.mkd][bc] for all the details you might need.
+
+ There are 3 other settings related to big configs. They are changed only
+ in rare cases, however, so are described later.
+
+ * `$GL_NO_DAEMON_NO_GITWEB`, boolean, default 0
+
+ If you have *lots* of repos, and you're *not* using gitweb or daemon, you
+ should probably set this on for efficiency. Despite the name, it also
+ blocks repo config settings. Please read [doc/big-config.mkd][bc] for
+ more details.
+
+<a name="_variables_with_a_security_impact"></a>
+
+### variables with a security impact
+
+**IMPORTANT NOTE**
+
+This section describes variables that, if not carefully used, can cause
+security issues. It also includes variables which I personally do not use and
+do not have the ability to test thoroughly
+
+Using non-default value for these variables voids the security reward in the
+README. This does *not* mean they are less important or that I will ignore
+problems; it just means *my* ability to catch problems may be limited by my
+test suite, my actual production use, my time, and sometimes (LDAP comes to
+mind) even my skill or resources available to me, and that therefore I depend
+on feedback from my users to find or fix issues.
+
+ * `$GL_ALL_READ_ALL`, boolean, default undef
+
+ Eliminates the access control check for read access. Makes things much
+ (**much**!) faster when you have 10,000 projects and the compiled conf
+ file is more than 20MB in size! **Double check with your boss or have a
+ new job lined up before setting this on!**
+
+ * `$GIT_PATH`, string, default empty
+
+ If git on your server is on a standard path (that is `ssh git@server git
+ --version` works), leave this setting as is. Otherwise, find out where it
+ is and use that value here, for example `GIT_PATH="/opt/bin/";`
+
+ * `$GL_GITCONFIG_KEYS`, string, default empty
+
+ This setting allows the repo admin to define acceptable gitconfig keys.
+
+ 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 allow executing arbitrary commands!
+
+ You have 3 choices. By default `$GL_GITCONFIG_KEYS` is left empty, which
+ completely disables this feature (meaning you cannot set git configs via
+ the repo config).
+
+ The second choice is to give it a space separated list of settings you
+ consider safe. (These are actually treated as a set of perl regular
+ expression patterns, and any one of them must match). For example:
+ `$GL_GITCONFIG_KEYS = "core\\.logAllRefUpdates core\\..*compression";`
+ allows repo admins to set one of those 3 config keys (yes, that second
+ pattern matches two settings from "man git-config", if you look).
+
+ The third choice (which you may have guessed already if you're familiar
+ with regular expressions) is to allow anything and everything:
+ `$GL_GITCONFIG_KEYS = ".*";`
+
+ NOTE that due to some quoting and interpolation issues I have not been
+ able to look at, a literal "." needs to be specified in this string as
+ `\\.` (two backslashes and a dot). So this is how you'd allow any keys in
+ the "foo" category: `$GL_GITCONFIG_KEYS = "foo\\..*";`
+
+ * `$GL_GITCONFIG_WILD`, boolean, default 0
+
+ This setting allows gitconfig keys even for wild repos. This is an
+ efficiency issue more than a security issue, since this requires trawling
+ through all of `$REPO_BASE` looking for stuff :)
+
+ * `$GL_NO_CREATE_REPOS`, boolean, default 0
+
+ DO NOT CHANGE THIS unless you have other means to create repos and
+ correctly populate them with the required hooks. No hooks, no access
+ control; you have been warned!
+
+ * `$GL_NO_SETUP_AUTHKEYS`, boolean, default 0
+
+ DO NOT CHANGE THIS unless you have other means to setup the authkeys file
+ (`~/.ssh/authorized_keys`). In an extreme case, if you switch this on
+ without also fixing up the authkeys file, users who you think you deleted
+ may still have access. All in all, please be careful, as with any change
+ that affects ssh.
+
+ * `$GL_WILDREPOS_DEFPERMS`, string, default undef
+
+ This sets default wildcard permissions for newly created wildcard repos.
+
+ If set, this value will be used as the default user-level permission rule
+ of new wildcard repositories. The user can change this value with the
+ setperms command as desired after repository creation; it is only a
+ default.
+
+ Example: `$GL_WILDREPOS_DEFPERMS = 'R @all';`
+
+ * `$HTPASSWD_FILE`, string, default empty
+
+ Gitolite can help users run the htpasswd command in a secure manner (since
+ gitolite has already identified them by an ssh key). If you want to
+ enable this, give the variable the absolute path to whatever file apache
+ (etc) expect to find the passwords in.
+
+ Look in [doc/3-faq-tips-etc.mkd][faq] ("easier to link gitweb
+ authorisation with gitolite" section) for more details on using this
+ feature.
+
+ * `$RSYNC_BASE`, string, default empty
+
+ Gitolite can be used to allow fine grained control of the rsync command.
+
+ This setting enables the rsync external command helper, by specifying the
+ base path of all the files that are accessible via rsync. It must be an
+ absolute path, like `$RSYNC_BASE = "/home/git/up-down";`. Leave it
+ undefined or set to the empty string to disable the rsync helper.
+
+ When enabled, it runs rsync with specific arguments, all presumably filled
+ in correctly by the client-side rsync. However, I am not an expert on how
+ rsync may be abused, so if it breaks, you get to keep both pieces!
+
+ * `$SVNSERVE`, string, default empty
+
+ Gitolite can also be used to gate access (though not at a fine grained
+ level) to SVN if needed, passing authentication information on to
+ `svnserve`. This setting allows launching svnserve when requested by the
+ ssh client. This allows using the same SSH setup for both SVN and git
+ access. Leave it undefined or set to the empty string to disable svnserve
+ access.
+
+ The setting will look something like (where the %u is substituted with the
+ username):
+
+ $SVNSERVE = "/usr/bin/svnserve -r /var/svn/ -t --tunnel-user=%u";
+
+ * hook chaining
+
+ * `$UPDATE_CHAINS_TO`, string, default "hooks/update.secondary"
+ * `$ADMIN_POST_UPDATE_CHAINS_TO`, string, default
+ "hooks/post-update.secondary"
+
+ By default, the update hook in every repo chains to "update.secondary".
+ Similarly, the post-update hook in the admin repo chains to
+ "post-update.secondary". If you're fine with the defaults, there's no
+ need to do anything here. However, if you want to use different names or
+ paths, change these variables.
+
+ * `$GL_ADC_PATH`, string, default undef
+
+ This setting enables admin defined commands.
+
+ **WARNING**: Use this feature only if (a) you really know what you're
+ doing and (b) you really, **really**, know what you're doing! Please read
+ [doc/admin-defined-commands.mkd][adc] for details. This is an extremely
+ powerful and flexible feature, and naturally anything that flexible can be
+ a security risk!
+
+ * `$GL_GET_MEMBERSHIPS_PGM`, string, default undef
+
+ 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. See
+ [doc/big-config.mkd][bc] for more details.
+
+ Example: `$GL_GET_MEMBERSHIPS_PGM = "/usr/local/bin/expand-ldap-user-to-groups"`
+
+<a name="_less_used_changed_variables"></a>
+
+### less used/changed variables
+
+ * `$GL_ALL_INCLUDES_SPECIAL`, boolean, default undef
+
+ Giving access to @all users (as in `R = @all`) in the config normally
+ does *not* include the special users "gitweb" and "daemon". If you want
+ @all to include these two users, set this variable.
+
+ * mirroring setup
+
+ These two variables enable mirroring support; see
+ [doc/mirroring.mkd][mirr] for details. The two variables are
+ `$GL_SLAVE_MODE`, (boolean, default undef), and `$ENV{GL_SLAVES}`,
+ (environment variable, string, default undef)
+
+ Note on the second variable above: you must use single quotes to give it
+ its value, not double quotes, (like `$ENV{GL_SLAVES} = 'gitolite@server2
+ gitolite@server3';`). Also note that this is an environment variable, not
+ a regular perl variable, so mind the syntax if you're not a perl guy :-)
+
+ * `$GL_WILDREPOS_PERM_CATS`, string, default "READERS WRITERS"
+
+ Originally, we only allowed "R" and "RW" in the setperms command. Now we
+ allow the admin to define other categories as she wishes (example:
+ MANAGERS, TESTERS, etc).
+
+ This variable is a space-separated list of the allowed categories.
+
+ PLEASE, *PLEASE*, read the section in
+ [doc/wildcard-repositories.mkd][wild] for caveats and warnings. This is a
+ VERY powerful feature and if you're not careful you could mess up the ACLs
+ nicely.
+
+ This is the internal default if you don't set it (like if you didn't
+ update your ~/.gitolite.rc with new variables when you upgraded gitolite):
+
+ $GL_WILDREPOS_PERM_CATS = "READERS WRITERS";
+
+ You can use your own categories in addition to the standard ones; I
+ suggest you include READERS and WRITERS for backward compatbility though:
+
+ $GL_WILDREPOS_PERM_CATS = "READERS WRITERS MANAGERS TESTERS";
+
+<a name="_rarely_changed_variables"></a>
+
+### rarely changed variables
+
+ * `$GL_LOGT`, string, default `$GL_ADMINDIR/logs/gitolite-%y-%m.log`
+
+ This is the template for location of the log files and format of their
+ names.
+
+ The default produces files like `~/.gitolite/logs/gitolite-2009-09.log`.
+ If you make up your own templates, **PLEASE MAKE SURE** the directory
+ exists and is writable; gitolite won't do that for you unless it is the
+ default, ("$GL_ADMINDIR/logs")
+
+ * `$GL_PERFLOGT`, string, default undef
+
+ This gives the location of the performance log files. Uncomment and set
+ this variable if you want performance logging. Performance log files are
+ kept separate from access log files because they store different, usually
+ much shorter term, information.
+
+ * `$GL_SITE_INFO`, string, default undef
+
+ Some installations would like to give their users customised information
+ (like a link to their own websites, for example) so that users have a
+ quick way to find some links or information.
+
+ If this variable is defined, the "info" command will print it at the end
+ of the listing.
+
+ * `$REPO_BASE`, string, default "repositories"
+
+ This is where all the repos go. If it's not an absolute path, it is
+ considered to be relative to $HOME. Changing it after the install has
+ completed is doable, but tricky if you don't know how gitolite works.
+
+[wild]: http://github.com/sitaramc/gitolite/blob/pu/doc/wildcard-repositories.mkd
+[bc]: http://github.com/sitaramc/gitolite/blob/pu/doc/big-config.mkd
+[faq]: http://github.com/sitaramc/gitolite/blob/pu/doc/3-faq-tips-etc.mkd
+[adc]: http://github.com/sitaramc/gitolite/blob/pu/doc/admin-defined-commands.mkd
+[mirr]: http://github.com/sitaramc/gitolite/blob/pu/doc/mirroring.mkd
diff --git a/doc/install-transcript.mkd b/doc/install-transcript.mkd
index 1a3bcbc..178ba1a 100644
--- a/doc/install-transcript.mkd
+++ b/doc/install-transcript.mkd
@@ -127,7 +127,7 @@ described in the `ssh-copy-id` section in `doc/3-faq-tips-etc.mkd`).
| .. |
+-----------------+
- sita@sita-lt:~ $ ssh-copy-id -i ~/.ssh/id_rsa git@server
+ sita@sita-lt:~ $ ssh-copy-id -i ~/.ssh/id_rsa.pub git@server
git@server's password:
/usr/bin/xauth: creating new authority file /home/git/.Xauthority
Now try logging into the machine, with "ssh 'git@server'", and check in:
diff --git a/doc/overkill.mkd b/doc/overkill.mkd
index bb85e89..c71ccd6 100644
--- a/doc/overkill.mkd
+++ b/doc/overkill.mkd
@@ -23,13 +23,9 @@ repos, you can use plain Unix permissions to get a lot of this done:
git init --bare --shared reponame.git
* For each user who needs access to the repos, add them as members to the
- "git" group also. On Mandriva this is:
+ "git" group also. On Fedora this is:
- usermod -G git username
-
- Don't forget that `-G` *replaces* the list of supplementary groups for the
- user, so be sure to first check if he is already member of some groups and
- keep those in the command (comma-separated).
+ usermod -a -G git username
And that's basically it. The "init --shared" will create the repos with
"chmod -R g+s". If you have existing repos where you forgot (or didn't know)
diff --git a/doc/progit-article.mkd b/doc/progit-article.mkd
index da016d3..2667c9b 100644
--- a/doc/progit-article.mkd
+++ b/doc/progit-article.mkd
@@ -24,7 +24,7 @@ We will describe this last method in this article; for the other methods please
You start by obtaining public key based access to your server, so that you can log in from your workstation to the server without getting a password prompt. The following method works on Linux; for other workstation OSs you may have to do this manually. We assume you already had a key pair generated using `ssh-keygen`.
- $ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver
+ $ ssh-copy-id -i ~/.ssh/id_rsa.pub gitolite@gitserver
This will ask you for the password to the gitolite account, and then set up public key access. This is **essential** for the install script, so check to make sure you can run a command without getting a password prompt:
diff --git a/doc/ssh-troubleshooting.mkd b/doc/ssh-troubleshooting.mkd
index 6238cf9..0fa7169 100644
--- a/doc/ssh-troubleshooting.mkd
+++ b/doc/ssh-troubleshooting.mkd
@@ -307,7 +307,7 @@ from scratch:
`sitaram`, along with corresponding `.pub` files). Create them if needed.
Also make sure they are *different* and not a copy of each other :-)
* install gitolite normally:
- * run `ssh-copy-id -i ~/.ssh/id_rsa git@server` to get passwordless
+ * run `ssh-copy-id -i ~/.ssh/id_rsa.pub git@server` to get passwordless
access to the server. (Mac users may have to do this step manually)
* make sure `ssh git@server pwd` prints the `$HOME` of `git@server`
**without** asking for a password. Do not proceed till this works.
diff --git a/doc/who-uses-it.mkd b/doc/who-uses-it.mkd
index f3ecb08..82871f3 100644
--- a/doc/who-uses-it.mkd
+++ b/doc/who-uses-it.mkd
@@ -50,3 +50,8 @@ users as well.
[gentoo1]: http://archives.gentoo.org/gentoo-dev/msg_2812c9b9e768f64b46360ab17b9d0024.xml
[gentoo2]: http://www.gentoo.org/proj/en/overlays/
+
+**Nokia MeeGo** uses Gitolite internally, and has also contributed LDAP
+specific code (see [contrib/ldap][ldap] directory for details).
+
+[ldap]: http://github.com/sitaramc/gitolite/blob/pu/contrib/ldap
diff --git a/src/gitolite.pm b/src/gitolite.pm
index 550cf1c..63f7612 100644
--- a/src/gitolite.pm
+++ b/src/gitolite.pm
@@ -46,9 +46,14 @@ our $ADC_CMD_ARGS_PATT=qr(^[0-9a-zA-Z._\@/+:-]*$);
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, $GL_WILDREPOS_PERM_CATS, $GL_KEYDIR, @GL_METADATA, @GL_METADATA_REQUIRED);
our %repos;
our %groups;
-our %repo_config;
+our %git_configs;
+our %split_conf;;
our $data_version;
-our $current_data_version = '1.6';
+our $current_data_version = '1.7';
+
+# the following are read in from individual repo's gl-conf files, if present
+our %one_repo;
+our %one_git_config;
# ----------------------------------------------------------------------------
# convenience subs
@@ -154,21 +159,21 @@ sub check_ref {
# permission must also match the action (W or +) being attempted. If none
# of them match, the access is denied.
- # Notice that the function DIES!!! Any future changes that require more
- # work to be done *after* this, even on failure, can start using return
- # codes etc., but for now we're happy to just die.
+ # Notice that the function DIES unless a non-false 5th argument is present
- my ($allowed_refs, $repo, $ref, $perm) = @_;
+ my ($allowed_refs, $repo, $ref, $perm, $dry_run) = @_;
my @allowed_refs = sort { $a->[0] <=> $b->[0] } @{$allowed_refs};
for my $ar (@allowed_refs) {
my $refex = $ar->[1];
# refex? sure -- a regex to match a ref against :)
next unless $ref =~ /^$refex/;
+ return "DENIED by $refex" if $ar->[2] eq '-' and $dry_run;
die "$perm $ref $ENV{GL_USER} DENIED by $refex\n" if $ar->[2] eq '-';
# as far as *this* ref is concerned we're ok
return $refex if ($ar->[2] =~ /\Q$perm/);
}
+ return "DENIED by fallthru" if $dry_run;
die "$perm $ref $repo $ENV{GL_USER} DENIED by fallthru\n";
}
@@ -183,33 +188,19 @@ sub ln_sf
}
}
-# collect repo patterns for all %repos
-
-# for each repo passed (actual repos only please!), use either its own name if
-# it exists as is in the repos hash, or find and use the pattern that matches
-
-sub collect_repo_patts
+# list physical repos
+sub list_phy_repos
{
- my $repos_p = shift;
- my %repo_patts = ();
+ my @phy_repos;
wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
for my $repo (`find . -type d -name "*.git"`) {
chomp ($repo);
$repo =~ s(\./(.*)\.git$)($1);
- # the key has to be in the list, since the repo physically exists
- # -- my($perm, $creator, $wild) = &repo_rights($repo);
- # -- $repo_patts{$repo} = $wild || $repo;
- # turns out we're not using the value anywhere, so no point wasting
- # all those cycles getting all repos' rights, at least until a real
- # use for it comes along. But when it does come along, remember that
- # $wild is now a space separated list of matching patterns (or empty
- # if no wild patterns matched $repo). It is NOT a single value
- # anymore!
- $repo_patts{$repo} = 1;
+ push @phy_repos, $repo;
}
- return %repo_patts;
+ return @phy_repos;
}
@@ -268,8 +259,15 @@ sub where_is_rc
return if $ENV{GL_RC};
- my $glrc = $ENV{HOME} . "/.gitolite.rc";
- $ENV{GL_RC} = $glrc if (-f $glrc);
+ # Fedora doesn't actually have a "hosting user" at all (yeah -- bet you
+ # didn't know gitolite was *that* flexible!), so there's no fixed $HOME,
+ # and they prefer to keep their RC file in /etc/gitolite.
+ for my $glrc ( $ENV{HOME} . "/.gitolite.rc", "/etc/gitolite/gitolite.rc" ) {
+ if (-f $glrc) {
+ $ENV{GL_RC} = $glrc;
+ last;
+ }
+ }
}
# ----------------------------------------------------------------------------
@@ -312,16 +310,10 @@ sub new_repo
# ----------------------------------------------------------------------------
{
- # the following sub needs some persistent data, so we make a closure
+ # the following subs need some persistent data, so we make a closure
my $cache_filled = 0;
my %cached_groups;
-
- # "who created this repo", "am I on the R list", and "am I on the RW list"?
- sub wild_repo_rights
- {
- # set default categories
- $GL_WILDREPOS_PERM_CATS ||= "READERS WRITERS";
- my ($repo, $user) = @_;
+ sub fill_cache {
# pull in basic group info
unless ($cache_filled) {
local(%repos, %groups);
@@ -336,6 +328,15 @@ sub new_repo
%cached_groups = %groups;
$cache_filled++;
}
+ }
+
+ # "who created this repo", "am I on the R list", and "am I on the RW list"?
+ sub wild_repo_rights
+ {
+ # set default categories
+ $GL_WILDREPOS_PERM_CATS ||= "READERS WRITERS";
+ my ($repo, $user) = @_;
+
# creator
my $c = '';
if ( -f "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-creater") {
@@ -364,6 +365,7 @@ sub new_repo
# file). We replace each @foo with $user if $cached_groups{'@foo'}{$user}
# exists (i.e., $user is a member of @foo)
for my $g ($perms =~ /\s(\@\S+)/g) {
+ fill_cache(); # get %cached_groups
$perms =~ s/ $g(?!\S)/ $user/ if $cached_groups{$g}{$user};
}
# now setup the perm_cats hash to be returned
@@ -449,14 +451,14 @@ sub get_set_desc
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
-# set/unset repo configs
+# set/unset git configs
# ----------------------------------------------------------------------------
-sub setup_repo_configs
+sub setup_git_configs
{
- my ($repo, $repo_config_p) = @_;
+ my ($repo, $git_configs_p) = @_;
- while ( my ($key, $value) = each(%{ $repo_config_p->{$repo} }) ) {
+ while ( my ($key, $value) = each(%{ $git_configs_p->{$repo} }) ) {
if ($value) {
$value =~ s/^"(.*)"$/$1/;
system("git", "config", $key, $value);
@@ -555,8 +557,6 @@ sub parse_acl
%repos = %saved_repos; %groups = %saved_groups;
} else {
die "parse $GL_CONF_COMPILED failed: " . ($! or $@) unless do $GL_CONF_COMPILED;
- $saved_crwu = "$creator,$perm_cats_sig,$gl_user";
- %saved_repos = %repos; %saved_groups = %groups;
}
unless (defined($data_version) and $data_version eq $current_data_version) {
# this cannot happen for 'easy-install' cases, by the way...
@@ -565,6 +565,9 @@ sub parse_acl
die "parse $GL_CONF_COMPILED failed: " . ($! or $@) unless do $GL_CONF_COMPILED;
}
+ $saved_crwu = "$creator,$perm_cats_sig,$gl_user";
+ %saved_repos = %repos; %saved_groups = %groups;
+ add_repo_conf($repo) if $repo;
# basic access reporting doesn't send $repo, and doesn't need to; you just
# want the config dumped as is, really
@@ -584,7 +587,7 @@ sub parse_acl
$repos{$dr}{DELETE_IS_D} = 1 if $repos{$r}{DELETE_IS_D};
$repos{$dr}{CREATE_IS_C} = 1 if $repos{$r}{CREATE_IS_C};
$repos{$dr}{NAME_LIMITS} = 1 if $repos{$r}{NAME_LIMITS};
- $repo_config{$dr} = $repo_config{$r} if $repo_config{$r};
+ $git_configs{$dr} = $git_configs{$r} if $git_configs{$r};
for my $u ('@all', "$gl_user - wild", @user_plus, keys %perm_cats) {
my $du = $gl_user; $du = '@all' if $u eq '@all' or ($perm_cats{$u} || '') eq '@all';
@@ -603,6 +606,17 @@ sub parse_acl
return ($wild);
}
+# add repo conf from repo.git/gl-conf
+sub add_repo_conf
+{
+ my ($repo) = shift;
+ return unless $split_conf{$repo};
+ do "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-conf" or return;
+ $repos{$repo} = $one_repo{$repo};
+ $git_configs{$repo} = $one_git_config{$repo};
+}
+
+
# ----------------------------------------------------------------------------
# print a report of $user's basic permissions
# ----------------------------------------------------------------------------
@@ -639,6 +653,8 @@ sub report_basic
local $ENV{GL_USER} = $user;
&parse_acl($GL_CONF_COMPILED, "", "CREATOR");
+ # all we need is for 'keys %repos' to come up with all the names, so:
+ @repos{ keys %split_conf } = values %split_conf if %split_conf;
# send back some useful info if no command was given
&report_version($GL_ADMINDIR, $user);
@@ -773,10 +789,9 @@ sub expand_wild
# helper/convenience routine to get rights and ownership from a shell command
sub cli_repo_rights {
- my ($perm, $creator, $wild) = &repo_rights($_[0]);
- $perm =~ s/ /_/g;
- $creator =~ s/^\(|\)$//g;
- print "$perm $creator\n";
+ # check_access does a lot more, so just call it. Since it returns perms
+ # and creator separately, just space-join them and print it.
+ print join(" ", &check_access($_[0])), "\n";
}
sub can_read {
@@ -1090,10 +1105,13 @@ sub get_memberships {
sub check_access
{
- my ($GL_CONF_COMPILED, $repo, $path, $perm) = @_;
- my $ref = "NAME/$path";
+ my ($repo, $ref, $aa, $dry_run) = @_;
+ # aa = attempted access
- &parse_acl($GL_CONF_COMPILED);
+ my ($perm, $creator, $wild) = &repo_rights($repo);
+ $perm =~ s/ /_/g;
+ $creator =~ s/^\(|\)$//g;
+ return ($perm, $creator) unless $ref;
# until I do some major refactoring (which will bloat the update hook a
# bit, sadly), this code duplicates stuff in the current update hook.
@@ -1106,7 +1124,11 @@ sub check_access
push @allowed_refs, @ { $repos{'@all'}{$ENV{GL_USER}} || [] };
push @allowed_refs, @ { $repos{$repo}{'@all'} || [] };
- &check_ref(\@allowed_refs, $repo, $ref, $perm);
+ if ($dry_run) {
+ return &check_ref(\@allowed_refs, $repo, $ref, $aa, $dry_run);
+ } else {
+ &check_ref(\@allowed_refs, $repo, $ref, $aa);
+ }
}
# ----------------------------------------------------------------------------
@@ -1136,7 +1158,7 @@ sub ext_cmd_rsync
# ok now check if we're permitted to execute a $perm action on $path
# (taken as a refex) using rsync.
- &check_access($GL_CONF_COMPILED, 'EXTCMD/rsync', $path, $perm);
+ &check_access('EXTCMD/rsync', "NAME/$path", $perm);
# that should "die" if there's a problem
wrap_chdir($RSYNC_BASE);
diff --git a/src/gl-auth-command b/src/gl-auth-command
index e2ea9f5..2f32dc1 100755
--- a/src/gl-auth-command
+++ b/src/gl-auth-command
@@ -32,12 +32,13 @@ use warnings;
# ----------------------------------------------------------------------------
# these are set by the "rc" file
-our ($GL_LOGT, $GL_CONF_COMPILED, $REPO_BASE, $GIT_PATH, $REPO_UMASK, $GL_ADMINDIR, $RSYNC_BASE, $HTPASSWD_FILE, $GL_WILDREPOS, $GL_WILDREPOS_DEFPERMS, $GL_ADC_PATH, $SVNSERVE, $PROJECTS_LIST, $GL_SLAVE_MODE, $GL_PERFLOGT, @GL_METADATA);
+our ($GL_LOGT, $GL_CONF_COMPILED, $REPO_BASE, $GIT_PATH, $REPO_UMASK, $GL_ADMINDIR, $RSYNC_BASE, $HTPASSWD_FILE, $GL_WILDREPOS, $GL_WILDREPOS_DEFPERMS, $GL_ADC_PATH, $SVNSERVE, $PROJECTS_LIST, $GL_SLAVE_MODE, $GL_PERFLOGT, $GL_ALL_READ_ALL, @GL_METADATA);
# and these are set by gitolite.pm
our ($R_COMMANDS, $W_COMMANDS, $REPONAME_PATT, $REPOPATT_PATT, $ADC_CMD_ARGS_PATT);
our %repos;
our %groups;
-our %repo_config;
+our %git_configs;
+our %split_conf;;
# the common setup module is in the same directory as this running program is
my $bindir = $0;
@@ -227,14 +228,19 @@ $ENV{GL_REPO}=$repo;
# first level permissions check
# ----------------------------------------------------------------------------
-my ($perm, $creator, $wild) = &repo_rights($repo);
+my ($perm, $creator, $wild);
+if ( $GL_ALL_READ_ALL and $verb =~ $R_COMMANDS and -d "$ENV{GL_REPO_BASE_ABS}/$repo.git") {
+ $perm = 'R';
+} else {
+ ($perm, $creator, $wild) = &repo_rights($repo);
+}
if ($perm =~ /C/) {
# it was missing, and you have create perms
wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
new_repo($repo, "$GL_ADMINDIR/hooks/common", $user);
# note pwd is now the bare "repo.git"; new_repo does that...
wrap_print("gl-perms", "$GL_WILDREPOS_DEFPERMS\n") if $GL_WILDREPOS_DEFPERMS;
- &setup_repo_configs($repo, \%repo_config);
+ &setup_git_configs($repo, \%git_configs);
&setup_daemon_access($repo);
&add_del_line ("$repo.git", $PROJECTS_LIST, &setup_gitweb_access($repo, '', ''));
wrap_chdir($ENV{HOME});
diff --git a/src/gl-compile-conf b/src/gl-compile-conf
index e962a9c..f8d35bb 100755
--- a/src/gl-compile-conf
+++ b/src/gl-compile-conf
@@ -92,6 +92,9 @@ our %groups = ();
# in between :)
my %repos = ();
+# repos whose ACLs don't make it into the main compiled config file
+my %split_conf = ();
+
# rule sequence number
my $rule_seq = 0;
@@ -105,8 +108,8 @@ our $current_data_version; # this comes from gitolite.pm
# catch usernames<->pubkeys mismatches; search for "lint" below
my %user_list = ();
-# repo configurations
-our %repo_config = ();
+# repo specific 'git config' stuff
+our %git_configs = ();
# gitweb descriptions and owners; plain text, keyed by "$repo.git"
my %desc = ();
@@ -274,7 +277,7 @@ sub parse_conf_line
}
}
}
- # configuration
+ # repo specific 'git config' stuff
elsif ($line =~ /^config (.+) = ?(.*)/)
{
my ($key, $value) = ($1, $2);
@@ -283,7 +286,7 @@ sub parse_conf_line
die "$ABRT git config $key not allowed\ncheck GL_GITCONFIG_KEYS in the rc file for how to allow it\n" if (@matched < 1);
for my $repo (@{ $repos_p }) # each repo in the current stanza
{
- $repo_config{$repo}{$key} = $value;
+ $git_configs{$repo}{$key} = $value;
# no problem if it's a plain repo (non-pattern, non-groupname)
# OR wild configs are allowed
unless ( ($repo =~ $REPONAME_PATT and $repo !~ /^@/) or $GL_GITCONFIG_WILD) {
@@ -405,26 +408,31 @@ for my $fragment_file (glob("conf/fragments/*.conf"))
parse_conf_file($fragment_file, $fragment);
}
-my $compiled_fh = wrap_open( ">", "$GL_CONF_COMPILED.new" );
-my $data_version = $current_data_version;
-print $compiled_fh Data::Dumper->Dump([$data_version], [qw(*data_version)]);
-my $dumped_data = Data::Dumper->Dump([\%repos], [qw(*repos)]);
-$dumped_data .= Data::Dumper->Dump([\%repo_config], [qw(*repo_config)]) if %repo_config;
-# the dump uses single quotes, but we convert any strings containing $creator
-# and $gl_user to double quoted strings. A bit sneaky, but not too much...
-$dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
-print $compiled_fh $dumped_data;
-if (%groups) {
- $dumped_data = Data::Dumper->Dump([\%groups], [qw(*groups)]);
- $dumped_data =~ s/\bCREAT[EO]R\b/\$creator/g;
+sub write_compiled_conf
+{
+ my $compiled_fh = wrap_open( ">", "$GL_CONF_COMPILED.new" );
+ my $data_version = $current_data_version;
+ print $compiled_fh Data::Dumper->Dump([$data_version], [qw(*data_version)]);
+ my $dumped_data = Data::Dumper->Dump([\%repos], [qw(*repos)]);
+ $dumped_data .= Data::Dumper->Dump([\%git_configs], [qw(*git_configs)]) if %git_configs;
+ # the dump uses single quotes, but we convert any strings containing $creator
+ # and $gl_user to double quoted strings. A bit sneaky, but not too much...
$dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
print $compiled_fh $dumped_data;
+ if (%groups) {
+ $dumped_data = Data::Dumper->Dump([\%groups], [qw(*groups)]);
+ $dumped_data =~ s/\bCREAT[EO]R\b/\$creator/g;
+ $dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
+ print $compiled_fh $dumped_data;
+ }
+ print $compiled_fh Data::Dumper->Dump([\%split_conf], [qw(*split_conf)]) if %split_conf;
+ close $compiled_fh or die "$ABRT close compiled-conf failed: $!\n";
+ rename "$GL_CONF_COMPILED.new", "$GL_CONF_COMPILED";
}
-close $compiled_fh or die "$ABRT close compiled-conf failed: $!\n";
-rename "$GL_CONF_COMPILED.new", "$GL_CONF_COMPILED";
# ----------------------------------------------------------------------------
-# (that ends the config file compiler and write)
+# (that ends the config file compiler, though we postpone the writing
+# for now to deal with the latest GL_BIG_CONFIG innovation!)
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
@@ -450,25 +458,31 @@ die "\n\t\t***** AAARGH! *****\n" .
"\tthe newer features, please upgrade.\n"
if $git_version < 10602; # that's 1.6.2 to you
-
-
-# ----------------------------------------------------------------------------
-# the rest of this program can be "switched off"; see doc/big-config.mkd for
-# details.
-# ----------------------------------------------------------------------------
-
# ----------------------------------------------------------------------------
-# any new repos to be created?
+# most of the rest of this program can be "switched off"; see
+# doc/big-config.mkd for details.
# ----------------------------------------------------------------------------
-# repo-base needs to be an absolute path for this loop to work right
+# repo-base needs to be an absolute path due to all the jumping around we do,
# so if it was not already absolute, prefix $HOME.
$ENV{GL_REPO_BASE_ABS} = ( $REPO_BASE =~ m(^/) ? $REPO_BASE : "$ENV{HOME}/$REPO_BASE" );
-unless ($GL_NO_CREATE_REPOS) {
+# process the normal repos in %repos. This includes creating them if needed
+# (and GL_NO_CREATE_REPOS is not set), checking hooks, and finally, if
+# GL_BIG_CONFIG is set, writing out the one-repo config file for directly
+# specified repos (i.e., "repo foo", not "@grp = foo" + "repo @grp")
+do_normal_repos();
+write_compiled_conf(); # write out the final compiled config
+
+# ----------------------------------------------------------------------------
+# process the normal repos in %repos (create, hook, one_repo config...)
+# ----------------------------------------------------------------------------
+
+sub do_normal_repos
+{
wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
- # autocreate repos. Start with the ones that are normal repos in %repos
+ # start with the ones that are normal repos in %repos
my @repos = grep { $_ =~ $REPONAME_PATT and not /^@/ } sort keys %repos;
# then, for each repogroup, find the members of the group and add them in
map { push @repos, keys %{ $groups{$_} } } grep { /^@/ } keys %repos;
@@ -477,39 +491,67 @@ unless ($GL_NO_CREATE_REPOS) {
@repos = sort keys %seen;
for my $repo (sort @repos) {
- next unless $repo =~ $REPONAME_PATT;
- next if $repo =~ m(^\@|EXTCMD/); # these are not real repos
- unless (-d "$repo.git") {
- print STDERR "creating $repo...\n";
- new_repo($repo, "$GL_ADMINDIR/hooks/common");
- # new_repo would have chdir'd us away; come back
- wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
- }
+ next unless $repo =~ $REPONAME_PATT; # skip repo patterns
+ next if $repo =~ m(^\@|EXTCMD/); # skip groups and fake repos
+
+ unless ($GL_NO_CREATE_REPOS) {
+ unless (-d "$repo.git") {
+ print STDERR "creating $repo...\n";
+ new_repo($repo, "$GL_ADMINDIR/hooks/common");
+ # new_repo would have chdir'd us away; come back
+ wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
+ }
- # 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. Perhaps we can make this easier now, and eliminate the easy
- # install, with a quick check (and a new, empty, "hook" as a sentinel)
- unless (-l "$repo.git/hooks/gitolite-hooked") {
- ln_sf("$GL_ADMINDIR/hooks/common", "*", "$repo.git/hooks");
- # in case of package install, GL_ADMINDIR is no longer the top cop;
- # override with the package hooks
- ln_sf("$GL_PACKAGE_HOOKS/common", "*", "$repo.git/hooks") if $GL_PACKAGE_HOOKS;
+ # 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. Perhaps we can make this easier now, and eliminate the easy
+ # install, with a quick check (and a new, empty, "hook" as a sentinel)
+ unless (-l "$repo.git/hooks/gitolite-hooked") {
+ ln_sf("$GL_ADMINDIR/hooks/common", "*", "$repo.git/hooks");
+ # in case of package install, GL_ADMINDIR is no longer the top cop;
+ # override with the package hooks
+ ln_sf("$GL_PACKAGE_HOOKS/common", "*", "$repo.git/hooks") if $GL_PACKAGE_HOOKS;
+ }
}
+
+ # write a one_repo config for normal repos declared directly (not just via a group)
+ write_1_compiled_conf($repo) if $GL_BIG_CONFIG and $repos{$repo} and -d "$repo.git";
}
}
-# ----------------------------------------------------------------------------
-# collect repo_patt for each actual repo
-# ----------------------------------------------------------------------------
+sub write_1_compiled_conf
+{
+ # warning: writes and *deletes* it from %repos and %git_configs
+ my ($repo) = shift;
+ my (%one_repo, %one_git_config);
-# go through each actual repo on disk, and match it to either its own name in
-# the config (non-wild) or a wild pattern that matches it. Lots of things
-# later will need this correspondence so we may as well snarf it in one shot
+ open(my $compiled_fh, ">", "$repo.git/gl-conf") or return;
+ $one_repo{$repo} = $repos{$repo};
+ delete $repos{$repo};
+ my $dumped_data = Data::Dumper->Dump([\%one_repo], [qw(*one_repo)]);
-my %repo_patts = ();
-%repo_patts = &collect_repo_patts(\%repos) unless $GL_NO_DAEMON_NO_GITWEB;
+ if ($git_configs{$repo}) {
+ $one_git_config{$repo} = $git_configs{$repo};
+ delete $git_configs{$repo};
+ $dumped_data .= Data::Dumper->Dump([\%one_git_config], [qw(*one_git_config)]);
+ }
+
+ # the dump uses single quotes, but we convert any strings containing $creator
+ # and $gl_user to double quoted strings. A bit sneaky, but not too much...
+ $dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
+ print $compiled_fh $dumped_data;
+ close $compiled_fh;
+
+ $split_conf{$repo} = 1;
+}
+
+# ----------------------------------------------------------------------------
+# get a list of physical repos for later
+# ----------------------------------------------------------------------------
+
+my @phy_repos = ();
+@phy_repos = &list_phy_repos() unless $GL_NO_DAEMON_NO_GITWEB;
# NOTE: we're overloading GL_NO_DAEMON_NO_GITWEB to mean "no git config" also.
# In fact anything that requires trawling through the existing repos doing
@@ -527,8 +569,6 @@ my %repo_patts = ();
# update repo configurations, gitweb description, daemon export-ok, etc
# ----------------------------------------------------------------------------
-# all these require a "chdir" to the repo, so we club them for efficiency
-
my %projlist = ();
# for each real repo (and remember this will be empty, thus skipping all this,
@@ -537,13 +577,13 @@ my %projlist = ();
# note: we do them in 2 separate loops to avoid breaking the optimisation in
# sub parse_acl (look for variable $saved_crwu)
-for my $repo (keys %repo_patts) {
+for my $repo (@phy_repos) {
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$repo.git");
# daemon is easy
&setup_daemon_access($repo);
}
-for my $repo (keys %repo_patts) {
+for my $repo (@phy_repos) {
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$repo.git");
# gitweb is a little more complicated. Here're some notes:
# - "setup_gitweb_access" also sets "owner", despite the name
@@ -562,9 +602,9 @@ for my $repo (keys %repo_patts) {
# calls (setup daemon or gitweb). The reason is that they call
# "can_read", which eventually calls parse_acl with the right "creator"
# set for the *current* repo, which in turn stores translated values for
- # $creator in the repo_config hash, which, (phew!) is needed for a match
- # that eventually gets you a valid $repo_config{} below
- &setup_repo_configs($repo, \%repo_config) if $repo_config{$repo};
+ # $creator in the git_configs hash, which, (phew!) is needed for a match
+ # that eventually gets you a valid $git_configs{} below
+ &setup_git_configs($repo, \%git_configs) if $git_configs{$repo};
}
# write out the project list
diff --git a/t/out/t01-repo-groups.1 b/t/out/t01-repo-groups.1
index 38119e0..2124ba6 100644
--- a/t/out/t01-repo-groups.1
+++ b/t/out/t01-repo-groups.1
@@ -1,4 +1,4 @@
-$data_version = '1.6';
+$data_version = '1.7';
%repos = (
'aa' => {
'R' => {
diff --git a/t/out/t01-repo-groups.1b b/t/out/t01-repo-groups.1b
index 90c9850..3275bcf 100644
--- a/t/out/t01-repo-groups.1b
+++ b/t/out/t01-repo-groups.1b
@@ -1,4 +1,4 @@
-$data_version = '1.6';
+$data_version = '1.7';
%repos = (
'aa' => {
'R' => {
diff --git a/t/out/t01-repo-groups.1bs b/t/out/t01-repo-groups.1bs
new file mode 100644
index 0000000..944fac4
--- /dev/null
+++ b/t/out/t01-repo-groups.1bs
@@ -0,0 +1,116 @@
+$data_version = '1.7';
+%repos = ();
+%split_conf = (
+ 'aa' => 1,
+ 'bb' => 1,
+ 'gitolite-admin' => 1,
+ 'testing' => 1
+);
+repositories/aa.git/gl-conf
+repositories/bb.git/gl-conf
+repositories/gitolite-admin.git/gl-conf
+repositories/testing.git/gl-conf
+%one_repo = (
+ 'aa' => {
+ 'R' => {
+ 'u1' => 1,
+ 'u2' => 1,
+ 'u3' => 1
+ },
+ 'W' => {
+ 'u1' => 1,
+ 'u2' => 1,
+ 'u3' => 1
+ },
+ 'u1' => [
+ [
+ 2,
+ 'refs/.*',
+ 'RW+'
+ ]
+ ],
+ 'u2' => [
+ [
+ 4,
+ 'refs/.*',
+ 'RW'
+ ]
+ ],
+ 'u3' => [
+ [
+ 5,
+ 'refs/.*',
+ 'RW'
+ ]
+ ]
+ }
+);
+%one_repo = (
+ 'bb' => {
+ 'R' => {
+ 'u1' => 1,
+ 'u2' => 1,
+ 'u3' => 1
+ },
+ 'W' => {
+ 'u1' => 1,
+ 'u2' => 1,
+ 'u3' => 1
+ },
+ 'u1' => [
+ [
+ 3,
+ 'refs/.*',
+ 'RW+'
+ ]
+ ],
+ 'u2' => [
+ [
+ 6,
+ 'refs/.*',
+ 'RW'
+ ]
+ ],
+ 'u3' => [
+ [
+ 7,
+ 'refs/.*',
+ 'RW'
+ ]
+ ]
+ }
+);
+%one_repo = (
+ 'gitolite-admin' => {
+ 'R' => {
+ 'tester' => 1
+ },
+ 'W' => {
+ 'tester' => 1
+ },
+ 'tester' => [
+ [
+ 0,
+ 'refs/.*',
+ 'RW+'
+ ]
+ ]
+ }
+);
+%one_repo = (
+ 'testing' => {
+ '@all' => [
+ [
+ 1,
+ 'refs/.*',
+ 'RW+'
+ ]
+ ],
+ 'R' => {
+ '@all' => 1
+ },
+ 'W' => {
+ '@all' => 1
+ }
+ }
+);
diff --git a/t/out/t01-repo-groups.2 b/t/out/t01-repo-groups.2
index d766ca0..5b6a9aa 100644
--- a/t/out/t01-repo-groups.2
+++ b/t/out/t01-repo-groups.2
@@ -1,4 +1,4 @@
-$data_version = '1.6';
+$data_version = '1.7';
%repos = (
'@g1' => {
'@g1' => [
@@ -23,7 +23,21 @@ $data_version = '1.6';
'@g1' => 1,
'@g2' => 1
}
- },
+ }
+);
+%groups = (
+ '@g1' => {
+ 'aa' => 'master',
+ 'bb' => 'master'
+ }
+);
+%split_conf = (
+ 'gitolite-admin' => 1,
+ 'testing' => 1
+);
+repositories/gitolite-admin.git/gl-conf
+repositories/testing.git/gl-conf
+%one_repo = (
'gitolite-admin' => {
'R' => {
'tester' => 1
@@ -38,7 +52,9 @@ $data_version = '1.6';
'RW+'
]
]
- },
+ }
+);
+%one_repo = (
'testing' => {
'@all' => [
[
@@ -55,9 +71,3 @@ $data_version = '1.6';
}
}
);
-%groups = (
- '@g1' => {
- 'aa' => 'master',
- 'bb' => 'master'
- }
-);
diff --git a/t/out/t02-user-groups.1 b/t/out/t02-user-groups.1
index d05ee68..05ba1fb 100644
--- a/t/out/t02-user-groups.1
+++ b/t/out/t02-user-groups.1
@@ -1,4 +1,4 @@
-$data_version = '1.6';
+$data_version = '1.7';
%repos = (
'aa' => {
'R' => {
diff --git a/t/out/t02-user-groups.1b b/t/out/t02-user-groups.1b
index d53203f..16d4f1b 100644
--- a/t/out/t02-user-groups.1b
+++ b/t/out/t02-user-groups.1b
@@ -1,4 +1,4 @@
-$data_version = '1.6';
+$data_version = '1.7';
%repos = (
'aa' => {
'R' => {
diff --git a/t/out/t02-user-groups.1bs b/t/out/t02-user-groups.1bs
new file mode 100644
index 0000000..54d8b4a
--- /dev/null
+++ b/t/out/t02-user-groups.1bs
@@ -0,0 +1,79 @@
+$data_version = '1.7';
+%repos = ();
+%split_conf = (
+ 'aa' => 1,
+ 'gitolite-admin' => 1,
+ 'testing' => 1
+);
+repositories/aa.git/gl-conf
+repositories/gitolite-admin.git/gl-conf
+repositories/testing.git/gl-conf
+%one_repo = (
+ 'aa' => {
+ 'R' => {
+ 'u1' => 1,
+ 'u2' => 1,
+ 'u3' => 1
+ },
+ 'W' => {
+ 'u1' => 1,
+ 'u2' => 1,
+ 'u3' => 1
+ },
+ 'u1' => [
+ [
+ 2,
+ 'refs/.*',
+ 'RW+'
+ ]
+ ],
+ 'u2' => [
+ [
+ 3,
+ 'refs/.*',
+ 'RW'
+ ]
+ ],
+ 'u3' => [
+ [
+ 4,
+ 'refs/.*',
+ 'RW'
+ ]
+ ]
+ }
+);
+%one_repo = (
+ 'gitolite-admin' => {
+ 'R' => {
+ 'tester' => 1
+ },
+ 'W' => {
+ 'tester' => 1
+ },
+ 'tester' => [
+ [
+ 0,
+ 'refs/.*',
+ 'RW+'
+ ]
+ ]
+ }
+);
+%one_repo = (
+ 'testing' => {
+ '@all' => [
+ [
+ 1,
+ 'refs/.*',
+ 'RW+'
+ ]
+ ],
+ 'R' => {
+ '@all' => 1
+ },
+ 'W' => {
+ '@all' => 1
+ }
+ }
+);
diff --git a/t/out/t02-user-groups.2 b/t/out/t02-user-groups.2
index be82819..b4d5fd1 100644
--- a/t/out/t02-user-groups.2
+++ b/t/out/t02-user-groups.2
@@ -1,4 +1,4 @@
-$data_version = '1.6';
+$data_version = '1.7';
%repos = (
'aa' => {
'@g1' => [
diff --git a/t/out/t02-user-groups.2bs b/t/out/t02-user-groups.2bs
new file mode 100644
index 0000000..0fc09d0
--- /dev/null
+++ b/t/out/t02-user-groups.2bs
@@ -0,0 +1,84 @@
+$data_version = '1.7';
+%repos = ();
+%groups = (
+ '@g1' => {
+ 'u1' => 'master'
+ },
+ '@g2' => {
+ 'u2' => 'master',
+ 'u3' => 'master'
+ },
+ '@g3' => {
+ 'u4' => 'master',
+ 'u5' => 'master',
+ 'u6' => 'master'
+ }
+);
+%split_conf = (
+ 'aa' => 1,
+ 'gitolite-admin' => 1,
+ 'testing' => 1
+);
+repositories/aa.git/gl-conf
+repositories/gitolite-admin.git/gl-conf
+repositories/testing.git/gl-conf
+%one_repo = (
+ 'aa' => {
+ '@g1' => [
+ [
+ 2,
+ 'refs/.*',
+ 'RW+'
+ ]
+ ],
+ '@g2' => [
+ [
+ 3,
+ 'refs/.*',
+ 'RW'
+ ]
+ ],
+ 'R' => {
+ '@g1' => 1,
+ '@g2' => 1
+ },
+ 'W' => {
+ '@g1' => 1,
+ '@g2' => 1
+ }
+ }
+);
+%one_repo = (
+ 'gitolite-admin' => {
+ 'R' => {
+ 'tester' => 1
+ },
+ 'W' => {
+ 'tester' => 1
+ },
+ 'tester' => [
+ [
+ 0,
+ 'refs/.*',
+ 'RW+'
+ ]
+ ]
+ }
+);
+%one_repo = (
+ 'testing' => {
+ '@all' => [
+ [
+ 1,
+ 'refs/.*',
+ 'RW+'
+ ]
+ ],
+ 'R' => {
+ '@all' => 1
+ },
+ 'W' => {
+ '@all' => 1
+ }
+ }
+);
diff --git a/t/t01-repo-groups b/t/t01-repo-groups
index 367e29d..86c7231 100644
--- a/t/t01-repo-groups
+++ b/t/t01-repo-groups
@@ -39,8 +39,8 @@ echo "
RW = u2 u3
" | ugc
-catconf
-expect_filesame $TESTDIR/out/t01-repo-groups.1
+catconfs
+expect_filesame $TESTDIR/out/t01-repo-groups.1bs
# ----------
$TESTDIR/rollback || die "rollback failed"
@@ -54,7 +54,7 @@ echo "
RW = @g2
" | ugc
-catconf
+catconfs
expect_filesame $TESTDIR/out/t01-repo-groups.2
name INTERNAL
diff --git a/t/t02-user-groups b/t/t02-user-groups
index 7b673cc..3fabcbd 100644
--- a/t/t02-user-groups
+++ b/t/t02-user-groups
@@ -42,8 +42,8 @@ echo "
RW = u2 u3
" | ugc
-catconf
-expect_filesame $TESTDIR/out/t02-user-groups.1
+catconfs
+expect_filesame $TESTDIR/out/t02-user-groups.1bs
# ----------
$TESTDIR/rollback || die "rollback failed"
@@ -60,7 +60,7 @@ echo "
RW = @g2
" | ugc
-catconf
-expect_filesame $TESTDIR/out/t02-user-groups.2
+catconfs
+expect_filesame $TESTDIR/out/t02-user-groups.2bs
name INTERNAL
diff --git a/t/t59-repo-not-on-disk b/t/t59-repo-not-on-disk
index 2873763..9f246f6 100644
--- a/t/t59-repo-not-on-disk
+++ b/t/t59-repo-not-on-disk
@@ -76,15 +76,21 @@ do
cd ~/td
name "repo on disk missing: u1"
runlocal git clone u1:aa
- expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "0" ] && expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "1" ] && expect "R access for aa DENIED to u1"
+ [ "$bc" = "1" ] && expect "Or there may be no repository at the given path. Did you spell it correctly?"
name "repo on disk missing: tester"
runlocal git clone gitolite:aa
- expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "0" ] && expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "1" ] && expect "R access for aa DENIED to tester"
+ [ "$bc" = "1" ] && expect "Or there may be no repository at the given path. Did you spell it correctly?"
name "repo on disk missing: u4"
runlocal git clone u4:aa
- expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "0" ] && expect "fatal: 'repositories/aa.git' does not appear to be a git repository"
+ [ "$bc" = "1" ] && expect "R access for aa DENIED to u4"
+ [ "$bc" = "1" ] && expect "Or there may be no repository at the given path. Did you spell it correctly?"
name "repo on disk missing: u6"
runlocal git clone u6:aa
diff --git a/t/test-driver.sh b/t/test-driver.sh
index 5d03753..78ba786 100755
--- a/t/test-driver.sh
+++ b/t/test-driver.sh
@@ -14,6 +14,13 @@ runremote() { ssh gitolite-test@localhost "$@" > ~/1 2> ~/2; }
listrepos() { ssh gitolite-test@localhost find repositories -type d -name "*.git" | sort > ~/1 2> ~/2; }
# remote cat compiled pm
catconf() { ssh gitolite-test@localhost cat .gitolite/conf/gitolite.conf-compiled.pm > ~/1 2> ~/2; }
+catconfs() {
+ (
+ ssh gitolite-test@localhost cat .gitolite/conf/gitolite.conf-compiled.pm
+ ssh gitolite-test@localhost find repositories -name gl-conf \| sort
+ ssh gitolite-test@localhost find repositories -name gl-conf \| sort \| xargs cat
+ ) > ~/1 2> ~/2
+}
# remote cat ~/.gitolite.rc
catrc() { ssh gitolite-test@localhost cat .gitolite.rc > ~/1 2> ~/2; }
# tail gitolite logfile