mirror of https://github.com/sipwise/ngcpcfg.git
Git doesn't track file permissions (except for the executable flag). For sensitive data (like the 'ssl' directory and file 'constants.yml' with passwords included) we've to prevent non-root users from accessing those files. hooks/pre-commit is inspired and based on the implementation as present in etckeeper (and luckily we're license compatible) and takes care of storing the file permissions inside file /etc/ngcp-config/.ngcpcfg_perms. The restore-permissions helper script takes care of restoring the permissions after cloning the ngcpcfg repository via ngcpcfg itself (being actions decrypt, pull (PRO-only) + initialise (PRO-only)). It can be executed manually as well via `usr/share/ngcp-ngcpcfg/helper/restore-permissions /etc/ngcp-config/` (or wherever the according ngcpcfg repository is placed at). Regarding the commit integration: git(1) itself doesn't track file permissions, so we can't detect changes to file permissions using git itself. Our new pre-commit hook records file permissions via the .ngcpcfg_perms file. Now by just invoking it during 'ngcpcfg commit' time we can ensure that even if there have been any file permission changes in the working directory the file .ngcpcfg_perms is then up2date and committed. JFTR: The solution via the git pre-commit hook ensures that no matter whether you're using 'ngcpcfg commit …' or 'git commit …' you always get the file permissions handled via .ngcpcfg_perms. Now if you want to change file permissions in a clean working directory and commit *without* using 'ngcpcfg commit' but directly via git itself then you've to use 'git commit --allow-empty ...' and thanks to the pre-commit hook the file .ngcpcfg_perms will still be up2date. Change-Id: I84d608585c626b52112ff649893e232e441c59d8changes/12/8012/12
parent
f009806409
commit
08f68c829b
@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
# Filename: /usr/share/ngcp-ngcpcfg/helper/restore-permissions
|
||||
# Purpose: restore file/directory permissions after git clone
|
||||
################################################################################
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
if [ "${#:-}" -ne 1 ] ; then
|
||||
echo "Usage: /usr/share/ngcp-ngcpcfg/helper/restore-permissions <ngcpcfg_directory>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# support for testsuite, assume defaults if unset
|
||||
CONFIG_POOL="${CONFIG_POOL:-/etc}"
|
||||
FUNCTIONS="${FUNCTIONS:-/usr/share/ngcp-ngcpcfg/functions/}"
|
||||
HELPER="${HELPER:-/usr/share/ngcp-ngcpcfg/helper/}"
|
||||
|
||||
. ${FUNCTIONS}/main
|
||||
|
||||
# used to run a command if the file it acts on (the last parameter) exists.
|
||||
maybe() {
|
||||
local command="$1"
|
||||
shift 1
|
||||
|
||||
if eval [ -e "\"\$$#\"" ] ; then
|
||||
"$command" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
target_directory="$1"
|
||||
if ! [ -d "${target_directory}" ] ; then
|
||||
log_errror "Directory ${target_directory} doesn't exist. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# should only be run on repositories you trust
|
||||
if ! [ -e "$target_directory"/.ngcpcfg_perms ]; then
|
||||
log_warn "Permission file ${target_directory}/.ngcpcfg_perms doesn't exist."
|
||||
else
|
||||
. "${target_directory}"/.ngcpcfg_perms
|
||||
fi
|
||||
|
||||
## END OF FILE #################################################################
|
||||
@ -0,0 +1,111 @@
|
||||
#!/bin/sh
|
||||
# pre-commit hook for ngcpcfg, to store metadata
|
||||
# implementation heavily based on etckeeper's pre-commit.d/30store-metadata
|
||||
|
||||
set -e
|
||||
|
||||
# ensure we're in the appropriate git directory when invoked directly
|
||||
# e.g. via `/etc/ngcp-config/.git/hooks/pre-commit` inside ngcpcfg
|
||||
if ! git rev-parse --git-dir >/dev/null 2>&1 ; then
|
||||
cd "$(dirname "${0}")"
|
||||
if git rev-parse --git-dir >/dev/null 2>&1 ; then
|
||||
git_dir="$(git rev-parse --git-dir)"
|
||||
cd "$(dirname "${git_dir}")"
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! git rev-parse --git-dir >/dev/null 2>&1 ; then
|
||||
echo "Warning: $(pwd) is not a git repository, ignoring $0"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
filter_ignore() {
|
||||
if [ -e ".gitignore" ]; then
|
||||
listfile="$( mktemp -t ngcpcfg-git.XXXXXXXXXX )"
|
||||
(git ls-files -oi --exclude-standard; git ls-files -oi --exclude-standard --directory) | sort | uniq > "$listfile" || true
|
||||
sed 's/^\.\///' | grep -xFvf "$listfile"
|
||||
rm -f "$listfile"
|
||||
unset listfile
|
||||
else
|
||||
cat -
|
||||
fi
|
||||
}
|
||||
|
||||
shellquote() {
|
||||
# Single quotes text, escaping existing single quotes.
|
||||
sed -e "s/'/'\"'\"'/g" -e "s/^/'/" -e "s/$/'/"
|
||||
}
|
||||
|
||||
generate_metadata() {
|
||||
# This function generates the script commands to fix any file
|
||||
# ownerships that aren't owner=root, group=root, as well as to
|
||||
# store the permissions of files.
|
||||
# The script is produced on stdout. Errors go to stderr.
|
||||
#
|
||||
# The script can use a 'maybe' function, which only runs a command
|
||||
# if the file in its last argument exists.
|
||||
|
||||
# We want files in the directory containing VCS data
|
||||
# but we want find to ignore the VCS files themselves.
|
||||
#
|
||||
# (Note that when using this, the find expression must end with
|
||||
# -print or -exec, else the excluded directories will actually be
|
||||
# printed!)
|
||||
|
||||
# Keep the sort order the same at all times.
|
||||
LC_COLLATE=C
|
||||
export LC_COLLATE
|
||||
|
||||
# git does not track directories,
|
||||
# so empty directories must be stored specially.
|
||||
find . -path ./.git -prune -o -type d -empty -print |
|
||||
sort | shellquote | sed -e "s/^/mkdir -p /"
|
||||
|
||||
# Store things that don't have the default user or group.
|
||||
# Store all file modes, in case the user has an unusual umask.
|
||||
find . -path ./.git -prune -o \( -type f -or -type d \) -print | filter_ignore | sort | perl -ne '
|
||||
BEGIN { $q=chr(39) }
|
||||
sub uidname {
|
||||
my $want=shift;
|
||||
if (exists $uidcache{$want}) {
|
||||
return $uidcache{$want};
|
||||
}
|
||||
my $name=scalar getpwuid($want);
|
||||
return $uidcache{$want}=defined $name ? $name : $want;
|
||||
}
|
||||
sub gidname {
|
||||
my $want=shift;
|
||||
if (exists $gidcache{$want}) {
|
||||
return $gidcache{$want};
|
||||
}
|
||||
my $name=scalar getgrgid($want);
|
||||
return $gidcache{$want}=defined $name ? $name : $want;
|
||||
}
|
||||
chomp;
|
||||
my @stat=stat($_);
|
||||
my $mode = $stat[2];
|
||||
my $uid = $stat[4];
|
||||
my $gid = $stat[5];
|
||||
s/$q/$q"$q"$q/g; # escape single quotes
|
||||
s/^/$q/;
|
||||
s/$/$q/;
|
||||
if ($uid != $>) {
|
||||
printf "maybe chown $q%s$q %s\n", uidname($uid), $_;
|
||||
}
|
||||
if ($gid != $)) {
|
||||
printf "maybe chgrp $q%s$q %s\n", gidname($gid), $_;
|
||||
}
|
||||
printf "maybe chmod %04o %s\n", $mode & 07777, $_;
|
||||
'
|
||||
}
|
||||
|
||||
echo "# Generated by ngcpcfg. Do not edit." > .ngcpcfg_perms
|
||||
echo >> .ngcpcfg_perms
|
||||
|
||||
# Make sure the file is not readable by others, since it can leak
|
||||
# information about contents of non-readable directories
|
||||
chmod 700 .ngcpcfg_perms
|
||||
|
||||
generate_metadata >> .ngcpcfg_perms
|
||||
|
||||
git add .ngcpcfg_perms
|
||||
Loading…
Reference in new issue