#!/bin/sh ######################################################### # Written Nov 13, 2007 and released under the GNU/GPLv2 ## # (c) Jeff Schroeder (jeffschroeder@computer.org) # # ######################################################### # # # # # restoreperms - restore permissions and fix ownership # # # on changed files from info in the rpm # # # database. Uses / Abuses rpm -V feature # # # # # ########################################################## # Idea inspired from a blog posting from Russell Coker # http://etbe.coker.com.au/2007/11/13/restorecon-equivalent-for-unix-permissions/ usage() { cat << EOF >&2 Usage: $0 -p rpmpackagename -f fix the permissions and file ownership back to what they should be if anything has changed -n dry-run mode. Don't actually do anything -l list the permissions on every file in a package from the rpmdb -c checks the permissions and ownership on every file against the same information in the rpm database. Displays any discrepancies EOF exit 1 } while getopts 'lfncp:' opt 2>/dev/null; do case "$opt" in l) LIST=true ;; p) PACKAGE="$OPTARG" ;; f) FIX=true ;; n) DRYRUN=true ;; c) COMPARE=true ;; *) usage ;; esac done ### Lets do some sanity checks # If called with 0 arguments test -z "$*" && usage # Is the package even installed? if (! /bin/rpm --quiet -q "$PACKAGE"); then echo "'${PACKAGE}' is not installed" >&2 usage fi if [ -z "$LIST" -a -z "$FIX" -a -z "$COMPARE" ]; then echo "Nothing to do..." >&2 usage fi if (! [ "$LIST" ] && /bin/rpm --quiet -V "$PACKAGE"); then echo "Nothing wrong with '${PACKAGE}'" exit 0 fi # -n option. Same as rsync shorthand if [ "$DRYRUN" = "true" ]; then RPM="echo /bin/rpm" else RPM=/bin/rpm fi # -l option if [ "$LIST" = "true" -a ! "$COMPARE" ]; then (echo "Listing of proper file permissions and ownership for '${PACKAGE}':"; \ /bin/rpm -q --qf '[%-15{FILEMODES:perms} %-9{FILEUSERNAME} %-9{FILEGROUPNAME} %{FILENAMES}\n]' $PACKAGE) exit 0 fi # -c option if [ "$COMPARE" = "true" ]; then # Put this all in a subshell so we can pipe it all to less ( echo "These files in '${PACKAGE}' have incorrect permissions or ownership:" # This is the magic that lets you seperate on newlines for the rpm --qf ... command IFS=" " # rpm doesn't have a perfect printf implementation so fudge a little to make it all match up with awk for properperms in `/bin/rpm -q --qf '[%-15{FILEMODES:perms} %-9{FILEUSERNAME} %-9{FILEGROUPNAME} %{FILENAMES}\n]' $PACKAGE`; do file=$(echo $properperms | awk '{print $NF}') realperms=$(ls -Al $file | awk '{printf "%-15s %-10s%-10s%s\n", $1, $3, $4, $NF }') if [ "$realperms" != "$properperms" ]; then echo "Current Info: $realperms" echo "Proper Info: $properperms" fi done ) fi # -f option to fix changed files permissions and ownership if [ "$FIX" = "true" ]; then status=$(/bin/rpm -V $PACKAGE 2>&1 | awk '{print $1}' | grep -o '[A-Z]') for opt in $status; do case "$opt" in M) $RPM --setperms $PACKAGE ;; U|G) # No point in setting them twice if the user and group are # both messed up. Be all intelligent and do it only once if [ "$PERMS" != "fixed" ]; then $RPM --setugids $PACKAGE && PERMS=fixed fi ;; esac done fi