From a9ce9965c06571a57522106691dac2f9892125ba Mon Sep 17 00:00:00 2001 From: Scott Bronson Date: Wed, 12 Mar 2008 16:15:10 -0700 Subject: Remove metastore, use simple find scripts instead. --- README | 13 +++----- debian/control | 4 +-- init.d/20restore-metadata | 12 +++---- pre-commit.d/30store-metadata | 67 ++++++++++++++++++++++++++++++---------- pre-commit.d/40warn-old-metadata | 7 +++++ 5 files changed, 68 insertions(+), 35 deletions(-) create mode 100755 pre-commit.d/40warn-old-metadata diff --git a/README b/README index 296b46f..98d2a09 100644 --- a/README +++ b/README @@ -1,14 +1,12 @@ etckeeper is a collection of tools to let /etc be stored in a git, mercurial, or bazaar repository. It hooks into apt to automatically -commit changes made to /etc during package upgrades. It uses -[metastore][1] to track file metadata that git does not normally +commit changes made to /etc during package upgrades. +It tracks file metadata that git does not normally support, but that is important for /etc, such as the permissions of `/etc/shadow`. It's quite modular and configurable, while also being simple to use if you understand the basics of working with version control. - [1]: http://david.hardeman.nu/software.php - ## security warnings First, a big warning: By checking /etc into revision control, you are @@ -47,10 +45,9 @@ storage, empty directories, and special files. Most VCS, including git, mercurial and bazaar have only limited tracking of file metadata, being able to track the executable bit, but not other -permissions or owner info. So file metadata storage is handled by -`metastore`. Among other chores, `etckeeper init` sets up a `pre-commit` -hook that uses `metastore` to store metadata about file owners, -permissions, and even extended attributes into a `/etc/.metadata` file. +permissions or owner info. So file metadata storage is stored separately. +Among other chores, `etckeeper init` sets up a `pre-commit` hook that stores +metadata about file owners and permissions into a `/etc/.metadata` file. This metadata is stored in version control along with everything else, and can be applied if the repo should need to be checked back out. diff --git a/debian/control b/debian/control index 87cb67c..9c7937d 100644 --- a/debian/control +++ b/debian/control @@ -10,11 +10,11 @@ Homepage: http://kitenet.net/~joey/code/etckeeper/ Package: etckeeper Architecture: all Section: admin -Depends: metastore, git-core (>= 1:1.5.4) | mercurial | bzr (>= 1.0), ${misc:Depends} +Depends: git-core (>= 1:1.5.4) | mercurial | bzr (>= 1.0), ${misc:Depends} Description: store /etc in git or mercurial The etckeeper program is a tool to let /etc be stored in a git, mercurial, or bzr repository. It hooks into APT to automatically commit changes made to - /etc during package upgrades. It uses 'metastore' to track file metadata that + /etc during package upgrades. It tracks file metadata that version control systems do not normally support, but that is important for /etc, such as the permissions of /etc/shadow. It's quite modular and configurable, while also being simple to use if you understand the basics of diff --git a/init.d/20restore-metadata b/init.d/20restore-metadata index 5d76b1b..be34bc7 100755 --- a/init.d/20restore-metadata +++ b/init.d/20restore-metadata @@ -1,12 +1,8 @@ #!/bin/sh set -e -# Note that metastore doesn't check that the .metastore file only changes -# perms of files in the current directory. It's ok to trust the .metastore -# file won't do anything shady, because, as documented, etckeeper-init -# should only be run on repositories you trust. -if [ -e .metadata ]; then - metastore --apply --mtime -else - metastore --save +# It's ok to trust that the .fix-metadata file won't do anything shady because, +# as documented, etckeeper-init should only be run on repositories you trust. +if [ -x .fix-metadata ]; then + ./.fix-metadata fi diff --git a/pre-commit.d/30store-metadata b/pre-commit.d/30store-metadata index 86e974c..5b8bd37 100755 --- a/pre-commit.d/30store-metadata +++ b/pre-commit.d/30store-metadata @@ -2,25 +2,58 @@ set -e if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ]; then - # Make sure the file is not readable by others, since it can leak - # information about contents of non-readable directories in /etc. - umask 077 - # ensure the file exists so that it will list its own metadata - if [ ! -e .metadata ]; then - metastore --save + if [ ! -e .fix-metadata ]; then + touch .fix-metadata + # Make sure the file is not readable by others, since it can leak + # information about contents of non-readable directories in /etc. + chmod 700 .fix-metadata fi - # metastore doesn't produce the same output file for the same metadata - # everytime, so avoid changing the file if nothing really changed. - if [ ! -z "$(metastore --compare)" ]; then - metastore --save - - # stage the file as part of the current commit - if [ "$VCS" = git ]; then - git add .metadata - fi - # hg and bzr add not done, they will automatically - # include the file in the current commit + echo "# Generated by etckeeper." > .fix-metadata + echo >> .fix-metadata + + + # Any files that aren't owner=root, group=root, or mode=0644 or 0755 + # will be fixed by the .fix-metadata script. Let's generate it. + + # Find all files and directories that don't have root as the owner + # Need to be sure UNKNOWN users and groups don't end up in the .fix-metadata + # file because chown and chgrp will choke on it. + output=$(find /etc \! -user root -exec stat --format="chown %U {}" {} \; | sort) + if [ -n "$output" ]; then + echo "$output" | grep "^chown UNKNOWN" >&2 || true + echo "$output" | grep -v "^chown UNKNOWN" >> .fix-metadata || true + fi + + # Find all files and directories that don't have root as the group + output=$(find /etc \! -group root -exec stat --format="chgrp %G {}" {} \; | sort) + if [ -n "$output" ]; then + echo "$output" | grep "^chgrp UNKNOWN" >&2 || true + echo "$output" | grep -v "^chgrp UNKNOWN" >> .fix-metadata || true + fi + + # Find all directories that aren't 0755 + find /etc -type d \! -perm 0755 -exec stat --format="chmod %a {}" {} \; \ + | sort >> .fix-metadata + + # Find all files that aren't either 0644 or 0755 (git keeps track of the + # executable bit so we don't have to). All the files in the + # /etc/.git/objects directory are 0444 so we'll specifically avoid it. + find /etc -wholename /etc/.git -prune -o \ + -type f \! -perm 0644 \! -perm 0755 -exec stat --format="chmod %a {}" {} \; \ + | sort >> .fix-metadata + + + # NOTE: we don't handle xattrs! + # Maybe check for getfattr/setfattr and use them if they're available? + + + # 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 .fix-metadata fi + # hg and bzr add not done, they will automatically + # include the file in the current commit fi diff --git a/pre-commit.d/40warn-old-metadata b/pre-commit.d/40warn-old-metadata new file mode 100755 index 0000000..374dd7b --- /dev/null +++ b/pre-commit.d/40warn-old-metadata @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +# Tell the user if the .metadata binary file is still lying around. +if [ -f .metadata ] && [ -f .fix-metadata ]; then + echo "etckeeper warning: The .metadata file is obsolete. You should delete it." >&2 +fi -- cgit v1.2.3