diff options
-rwxr-xr-x | perm_offset.py | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/perm_offset.py b/perm_offset.py index 4e13eb3..3f23ab1 100755 --- a/perm_offset.py +++ b/perm_offset.py @@ -3,6 +3,7 @@ import argparse import logging import os +from stat import S_IMODE, S_ISLNK import sys def remap_file(fpath, src, dst, count, dry_run): @@ -15,10 +16,21 @@ def remap_file(fpath, src, dst, count, dry_run): if gid >= src and gid < src + count: gid += dst - src - logging.debug('chown(%s, %d->%d, %d->%d)' % (fpath, stat.st_uid, uid, - stat.st_gid, gid)) - if not dry_run: - os.chown(fpath, uid, gid, follow_symlinks = False) + mode = S_IMODE(stat.st_mode) + + logging.debug('chown(%s, mode=%o %d->%d, %d->%d)' % + (fpath, mode, stat.st_uid, uid, stat.st_gid, gid)) + if dry_run: + return + + if S_ISLNK(stat.st_mode) and not os.chown in os.supports_follow_symlinks: + return + os.chown(fpath, uid, gid, follow_symlinks = False) + + # chown may clear setuid bits, so make sure to preserve them + if S_ISLNK(stat.st_mode) and not os.chmod in os.supports_follow_symlinks: + return + os.chmod(fpath, mode, follow_symlinks = False) parser = argparse.ArgumentParser( description = "Remap UIDs/GIDs in a directory tree from one range to another" |