From: Carl Baldwin <cnb@fc.hp.com>
To: Junio C Hamano <junkio@cox.net>, git@vger.kernel.org
Subject: Re: [RFC] Using sticky directories to control access to branches.
Date: Thu, 1 Dec 2005 08:42:22 -0700 [thread overview]
Message-ID: <20051201154222.GB18993@hpsvcnb.fc.hp.com> (raw)
In-Reply-To: <20051121180133.GA28171@hpsvcnb.fc.hp.com>
I have tweaked the script a little. I thought I'd send to the list in
case anyone was following this. If not, then safely ignore this.
#!/bin/bash
umask 002
# If you are having trouble with this access control hook script you can try
# setting this to true. It will tell you exactly why a user is being
# allowed/denied access.
verbose=false
# Default shell globbing messes things up downstream
GLOBIGNORE=*
function grant {
$verbose && echo >&2 "-Grant- $1"
echo grant
exit 0
}
function deny {
$verbose && echo >&2 "-Deny- $1"
echo deny
exit 1
}
function info {
$verbose && echo >&2 "-Info- $1"
}
# Implement generic branch and tag policies.
# - Tags should not be updated once created.
# - Branches should only be fast-forwarded.
case "$1" in
refs/tags/*)
[ -f "$GIT_DIR/$1" ] && deny >/dev/null "You can't overwrite an existing tag"
;;
refs/heads/*)
# No rebasing or rewinding
if expr "$2" : '0*$' >/dev/null; then
info "The branch '$1' is new..."
else
# updating -- make sure it is a fast forward
mb=$(git-merge-base "$2" "$3")
case "$mb,$2" in
"$2,$mb") info "Update is fast-forward" ;;
*) deny >/dev/null "This is not a fast-forward update." ;;
esac
fi
;;
*)
deny >/dev/null "Branch is not under refs/heads or refs/tags. What are you trying to do?"
;;
esac
# Implement per-branch controls based on username
allowed_users_file=$GIT_DIR/info/allowed-users
username=$(id -u -n)
info "The user is: '$username'"
if [ -f "$allowed_users_file" ]; then
rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' |
while read head_pattern user_patterns; do
matchlen=$(expr "$1" : "$head_pattern")
if [ "$matchlen" == "${#1}" ]; then
info "Found matching head pattern: '$head_pattern'"
for user_pattern in $user_patterns; do
info "Checking user: '$username' against pattern: '$user_pattern'"
matchlen=$(expr "$username" : "$user_pattern")
if [ "$matchlen" == "${#username}" ]; then
grant "Allowing user: '$username' with pattern: '$user_pattern'"
fi
done
deny "The user is not in the access list for this branch"
fi
done
)
case "$rc" in
grant) grant >/dev/null "Granting access based on $allowed_users_file" ;;
deny) deny >/dev/null "Denying access based on $allowed_users_file" ;;
*) ;;
esac
fi
allowed_groups_file=$GIT_DIR/info/allowed-groups
groups=$(id -G -n)
info "The user belongs to the following groups:"
info "'$groups'"
if [ -f "$allowed_groups_file" ]; then
rc=$(cat $allowed_groups_file | grep -v '^#' | grep -v '^$' |
while read head_pattern group_patterns; do
matchlen=$(expr "$1" : "$head_pattern")
if [ "$matchlen" == "${#1}" ]; then
info "Found matching head pattern: '$head_pattern'"
for group_pattern in $group_patterns; do
for groupname in $groups; do
info "Checking group: '$groupname' against pattern: '$group_pattern'"
matchlen=$(expr "$groupname" : "$group_pattern")
if [ "$matchlen" == "${#groupname}" ]; then
grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
fi
done
done
deny "None of the user's groups are in the access list for this branch"
fi
done
)
case "$rc" in
grant) grant >/dev/null "Granting access based on $allowed_groups_file" ;;
deny) deny >/dev/null "Denying access based on $allowed_groups_file" ;;
*) ;;
esac
fi
deny >/dev/null "There are no more rules to check. Denying access"
On Mon, Nov 21, 2005 at 11:01:33AM -0700, Carl Baldwin wrote:
> OK,
>
> To follow-up on this. Here is a final version of this script that was
> started by Junio. I polished it and made it work the way I want it.
> Hopefully, someone on the list will find it useful.
>
> Here is a basic description. There are two files:
> .git/info/allowed-users
> .git/info/allowed-groups
>
> The users file is checked, line by line, followed by the groups file.
> The first line matching the ref to be updated is used. Each line has
> one regular expression to match the ref followed by one or more regular
> expressions to match user (or group). Space is the delimeter so the RE
> cannot contain a space.
>
> If no line matches the ref then access is denied. For this reason I
> tend to include the following line as the last line of allowed-groups as
> the default since it will match any ref and any group.
>
> .* .*
>
> Here is the hook script... Thanks to Junio for getting me started. I
> rewrote the whole thing using my own style but much of the code is based
> on his.
>
> #!/bin/bash
>
> umask 002
>
> verbose=no
>
> # Default shell globbing messes things up later
> GLOBIGNORE=*
>
> function grant {
> [ "yes" == "$verbose" ] && echo >&2 "-Grant- $1"
> exit 0
> }
>
> function deny {
> [ "yes" == "$verbose" ] && echo >&2 "-Deny- $1"
> exit 1
> }
>
> function info {
> [ "yes" == "$verbose" ] && echo >&2 "-Info- $1"
> }
>
> # Implement generic branch and tag policies.
> # - Tags should not be updated once created.
> # - Branches should only be fast-forwarded.
> case "$1" in
> refs/tags/*)
> [ -f "$GIT_DIR/$1" ] && deny "You can't overwrite an existing tag"
> ;;
> refs/heads/*)
> # No rebasing or rewinding
> if expr "$2" : '0*$' >/dev/null; then
> info "The branch '$1' is new..."
> else
> # updating -- make sure it is a fast forward
> mb=$(git-merge-base "$2" "$3")
> case "$mb,$2" in
> "$2,$mb") info "Update is fast-forward" ;;
> *) deny "This is not a fast-forward update." ;;
> esac
> fi
> ;;
> *)
> deny "Branch is not under refs/heads or refs/tags. What are you trying to do?"
> ;;
> esac
>
> # Implement per-branch controls based on username
> allowed_users_file=$GIT_DIR/info/allowed-users
> username=$(id -u -n)
> info "The user is: '$username'"
>
> if [ -f "$allowed_users_file" ]; then
> 3<$allowed_users_file
> while read -u 3 head_pattern user_patterns; do
> matchlen=$(expr "$1" : "$head_pattern")
> if [ "$matchlen" == "${#1}" ]; then
> info "Found matching head pattern: '$head_pattern'"
> for user_pattern in $user_patterns; do
> info "Checking user: '$username' against pattern: '$user_pattern'"
> matchlen=$(expr "$username" : "$user_pattern")
> if [ "$matchlen" == "${#username}" ]; then
> grant "Allowing user: '$username' with pattern: '$user_pattern'"
> fi
> done
> deny "The user is not in the access list for this branch"
> fi
> done
> fi
>
> allowed_groups_file=$GIT_DIR/info/allowed-groups
> groups=$(id -G -n)
> info "The user belongs to the following groups:"
> info "'$groups'"
>
> if [ -f "$allowed_groups_file" ]; then
> 4<$allowed_groups_file
> while read -u 4 head_pattern group_patterns; do
> matchlen=$(expr "$1" : "$head_pattern")
> if [ "$matchlen" == "${#1}" ]; then
> info "Found matching head pattern: '$head_pattern'"
> for group_pattern in $group_patterns; do
> for groupname in $groups; do
> info "Checking group: '$groupname' against pattern: '$group_pattern'"
> matchlen=$(expr "$groupname" : "$group_pattern")
> if [ "$matchlen" == "${#groupname}" ]; then
> grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
> fi
> done
> done
> deny "None of the user's groups are in the access list for this branch"
> fi
> done
> fi
>
> deny "There are no more rules to check. Denying access"
> # End script here
>
> Carl
>
> --
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> Carl Baldwin Systems VLSI Laboratory
> Hewlett Packard Company
> MS 88 work: 970 898-1523
> 3404 E. Harmony Rd. work: Carl.N.Baldwin@hp.com
> Fort Collins, CO 80525 home: Carl@ecBaldwin.net
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Carl Baldwin Systems VLSI Laboratory
Hewlett Packard Company
MS 88 work: 970 898-1523
3404 E. Harmony Rd. work: Carl.N.Baldwin@hp.com
Fort Collins, CO 80525 home: Carl@ecBaldwin.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
next prev parent reply other threads:[~2005-12-01 15:42 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-17 17:01 [RFC] Using sticky directories to control access to branches Carl Baldwin
2005-11-18 7:55 ` Junio C Hamano
2005-11-21 18:01 ` Carl Baldwin
2005-11-21 19:29 ` Junio C Hamano
2005-12-01 15:42 ` Carl Baldwin [this message]
2005-12-02 1:13 ` Junio C Hamano
2005-12-02 9:29 ` Andreas Ericsson
2005-12-02 9:35 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20051201154222.GB18993@hpsvcnb.fc.hp.com \
--to=cnb@fc.hp.com \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).