Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sync file permissions *only*

A junior team member did a nasty chmod -R 777 in /etc/ and cause SSH cannot login remotely in a Ubuntu server. Now I fixed this login issue by manually set the correct file permissions on /etc/ssh/*, /etc/sudoers, /etc/ssl/* by comparing other normal system. But there are so many other files which may cause future issues.

I am thinking to use rsync to do the work, but don't want it to sync file contents, just permissions, no more work.

Is that possible? I see rsync has -a option but it does too much.

like image 943
kyrre Avatar asked Apr 15 '15 10:04

kyrre


2 Answers

Please note you can also try something that won't necessarily make you need to copy files from one place to another (depending on the filesize it may be desired)

You could use a mix of find and some grepping to generate a shell script to be executed on the host where you need to fix permissions.. you could use the same approach to generate a script for changing users/groups as well.. for example:

# find . -printf 'chmod %m %p #%M\n' | sort -k3 | grep -Pi '\s+\S*s\S*$'  > /var/tmp/fix_permissions.bash 
# bash /var/tmp/fix_permissions.bash

In the example above, what it does is to list all the files with their attributes in this format:

chmod 2755 ./addfs_7.1.0/bin #drwxr-sr-x
chmod 2755 ./addfs_7.1.0/config #drwxr-sr-x
chmod 2755 ./addfs_7.1.0 #drwxr-sr-x
chmod 2755 ./addfs_7.1.0/install #drwxr-sr-x
chmod 2755 ./addfs_7.1.0/library.dda #drwxr-sr-x
chmod 2755 ./addfs_7.1.0/library #drwxr-sr-x
chmod 2755 ./autosimimport #drwxr-sr-x

And in my case I only want to sync those with the 's' flag, so I filter with grep -Pi '\s+\S*s\S*$'. Sort was there as well because I had to compare the files in the other host.

TLDR

If you just want to apply all the permissions with no filtering or comparing:

  1. Create a script with the correct permissions on the "base" host

    find . -printf 'chmod %m %p\n' > /var/tmp/fix_permissions.sh

  2. Execute the script in the other host

    bash /var/tmp/fix_permissions.sh

like image 141
pimguilherme Avatar answered Oct 22 '22 04:10

pimguilherme


If you have the "normal" content of /etc available on the same system (like mounted in some other directory, let's say /mnt/correct/etc), you could use the --reference parameter to chmod and chown commands, and combine it with find that is started from the "normal" directory:

$ cd /mnt/correct/etc
$ find . ! -type l -exec chown -v --reference='{}' /etc/'{}' \;
$ find . ! -type l -exec chmod -v --reference='{}' /etc/'{}' \;

(I'm assuming you're on a UNIX system with GNU coreutils versions of chmod and chown.)

The "! -type l" condition in find excludes symbolic links, because otherwise chmod will use the link's permissions to change the file the link points to (and same applies to chown).

like image 31
Oleg Muravskiy Avatar answered Oct 22 '22 03:10

Oleg Muravskiy