#!/bin/bash # Original... # Copyright (c) 2000,2004 Matthias S. Benkmann
# You may do everything with this code except misrepresent its origin. # PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND! # Copyright (C) 2014 Steve Youngs # Rewrite, make it a lot more robost and handle most (all?) # possibilities of chown'ing. --SY. DAISY_CHAIN="" for p in $(type -ap chown) ; do if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p break fi done if [ ! -n "$DAISY_CHAIN" ]; then echo 1>&2 '***' Cannot find real ${0##*/} command exit 1 fi if [ $UID == 0 ]; then echo 1>&2 '***' $(dirname $0) should not be in root\'s \$PATH echo 1>&2 '***' call '"'$DAISY_CHAIN $@'"' directly. exit 1 fi # An ordinary user cannot change the UID of a file if that UID is # not their own, but chown can also be used to change the GID of a # file as well so it is feasible that an ordinary user could use # chown successfully. # preseve the command line as we're gonna mess with it. cmdline="$@" # strip off the options so that $1 becomes the UID:GID arg while [ -n "$1" ]; do case "$1" in (-*) shift ;; (*) break ;; esac done # Split USER:GROUP or USER.GROUP into USER and GROUP usrgrp="$1" usr=${usrgrp/[.:]*/} grp=${usrgrp/*[.:]/} report=0 # Catch the case where USER is somebody else. if [ -n "$usr" ]; then printf '%d' $usr &>/dev/null if [ $? -eq 0 ]; then if [ $usr -ne $(id -u) ]; then report=1 fi else if [ "$usr" != "$(id -un)" ]; then report=1 fi fi fi # Catch the case where GROUP isn't in our groups. if [ -n "$grp" -a $report -eq 0 ]; then GRP_CHAIN="" printf '%d' $grp &>/dev/null if [ $? -eq 0 ]; then GRP_LIST=$(id -G) else GRP_LIST=$(id -Gn) fi for g in ${GRP_LIST}; do if [ "$grp" == "$g" ]; then GRP_CHAIN=$g break fi done if [ -z "$GRP_CHAIN" ]; then report=1 fi fi if [ $report -eq 1 ]; then echo 1>&2 '***' chown ${cmdline} else exec $DAISY_CHAIN ${cmdline} || exit $? fi exit 0 # Local variables: # sh-basic-offset: 4 # End: