#!/bin/bash
+# Original...
# Copyright (c) 2000,2004 Matthias S. Benkmann <article AT winterdrache DOT de>
# 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 <steve@steveyoungs.com>
+# 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
done
if [ ! -n "$DAISY_CHAIN" ]; then
- echo Cannot find real ${0##*/} command
+ echo 1>&2 '***' Cannot find real ${0##*/} command
exit 1
fi
if [ $UID == 0 ]; then
- exec $DAISY_CHAIN "$@"
+ echo 1>&2 '***' $(dirname $0) should not be in root\'s \$PATH
+ echo 1>&2 '***' call '"'$DAISY_CHAIN $@'"' directly.
+ exit 1
fi
-if [ "$1" == "root.root" ]; then
- echo 1>&2 '***' chown "$@"
+# 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" && ("$usr" != "$(id -un)" ||
+ ($usr -ge 0 && $usr -ne $(id -u))) ]]; then
+ report=1
+fi
+
+# Catch the case where GROUP isn't in our groups.
+if [ -n "$grp" -a $report -eq 0 ]; then
+ GRP_CHAIN=""
+ if [ $grp -ge 0 2>/dev/null ]; 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
- $DAISY_CHAIN "$@" || exit $?
+ exec $DAISY_CHAIN "$cmdline" || exit $?
fi
exit 0
+
+# Local variables:
+# sh-basic-offset: 4
+# End: