#!/bin/sh set -e # Filters out UNKNOWN users and groups, prints a warning on stderr. filter_unknown() { CMD=$1 while read line; do # if the first n chars of $line equal "$CMD UNKNOWN "... if [ "$(printf %.$((9+${#CMD}))s "$line")" = "$CMD UNKNOWN " ]; then echo Bad "$2" for "$line" >&2 else echo "$line" fi done } generate_metadata() { # This function generates the script commands to fix any files # that aren't owner=root, group=root, or mode=0644 or 0755. # The script is produced on stdout. Errors go to stderr. # We maintain the permissions on the directory containing VCS data # but we want find to ignore the VCS files themselves. NOVCS='. -wholename ./.git -prune -o -wholename ./.bzr -prune -o -wholename ./.hg -prune -o' if [ "$VCS" = git ] || [ "$VCS" = hg ]; then # These version control systems do not track directories, # so empty directories must be stored specially. find -type d -empty | grep -v /.git/ | grep -v /.hg/ | grep -v /.bzr/ | sort | sed -e "s/^/mkdir -p '/" -e "s/\$/'/" fi # Find all files and directories that don't have root as the owner find $NOVCS \! -user root -exec stat --format="chown %U '{}'" {} \; \ | sort | filter_unknown chown owner # Find all files and directories that don't have root as the group find $NOVCS \! -group root -exec stat --format="chgrp %G '{}'" {} \; \ | sort | filter_unknown chgrp group # Find all directories that aren't 0755 find $NOVCS -type d \! -perm 0755 \ -exec stat --format="chmod %a '{}'" {} \; | sort # Find all files that aren't 0644 or 0755 (we can assume the VCS will # maintain the executable bit). find $NOVCS -type f \! -perm 0644 \! -perm 0755 \ -exec stat --format="chmod %a '{}'" {} \; | sort # We don't handle xattrs. # Maybe check for getfattr/setfattr and use them if they're available? } if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ]; then if [ -f .metadata ]; then # remove obsolete .metadata file # git allows fully deleting it at this point, other VCS # may not (the repo is locked for hg). if [ "$VCS" = git ]; then $VCS rm .metadata else rm -f .metadata fi fi echo "# Generated by etckeeper. Do not edit." > .etckeeper echo >> .etckeeper # Make sure the file is not readable by others, since it can leak # information about contents of non-readable directories in /etc. chmod 700 .etckeeper generate_metadata >> .etckeeper # stage the file as part of the current commit if [ "$VCS" = git ]; then # this will do nothing if the metadata file is unchanged. git add .etckeeper fi # hg and bzr add not done, they will automatically # include the file in the current commit fi