22

Is there a way to back up and restore file ownership and permissions (the things that can be changed with chown and chmod)?

You can do this in Windows using icacls.

What about access control lists?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
leeand00
  • 4,443
  • 10
  • 51
  • 78

3 Answers3

37

You can do this with the commands from the acl package (which should be available on all mainstream distributions, but might not be part of the base installation). They back up and restore ACL when ACL are present, but they also work for basic permissions even on systems that don't support ACL.

To back up permissions in the current directory and its subdirectories recursively:

getfacl -R . >permissions.facl

To restore permissions:

setfacl --restore=permissions.facl
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • Hmm. I _really_ need to read up on ACLs. – roaima Mar 10 '15 at 00:20
  • 1
    In the generated file, are they relative to a directory too? – leeand00 Mar 10 '15 at 01:10
  • 2
    @leeand00 Yes, the generated file always uses relative file names. – Gilles 'SO- stop being evil' Mar 10 '15 at 07:13
  • @Gilles,based on https://unix.stackexchange.com/questions/364517/difference-between-chmod-vs-acl,if `setfacl` files then cannot `chmod` again,maybe will cause conflict? – kittygirl Oct 02 '18 at 16:04
  • 1
    @kittygirl I have no idea what you're asking. What does “setfacl files then cannot chmod again” mean? What does this have to do with https://unix.stackexchange.com/questions/364517/difference-between-chmod-vs-acl,if ? What conflict? – Gilles 'SO- stop being evil' Oct 02 '18 at 16:16
  • @Gilles,consider ACL is not respected by other linux function like `cp`, I am afraid of using `setfacl`. – kittygirl Oct 03 '18 at 06:46
  • @Gilles,for the files only defined by `chmod` and `chown`,can `getfacl -R . >permissions.facl` and `setfacl --restore=permissions.facl` get the origin permission of these files? – kittygirl Oct 03 '18 at 07:05
  • @Gilles,does it work for filenames starting with whitespace, or containing non-printable characters? – kittygirl Oct 03 '18 at 13:08
  • @kittygirl Yes, including newlines. – Gilles 'SO- stop being evil' Oct 03 '18 at 13:48
  • @Gilles,there's big problem(maybe bug):run `setfacl` by root,cannot change a file like `-rw-r--r-- 1 root root`, – kittygirl Jan 11 '19 at 09:29
  • @kittygirl I don't understand your comment. When run by root, `setfacl` can change the permissions for any file. – Gilles 'SO- stop being evil' Jan 11 '19 at 09:59
  • @Gilles,actually I found a bug.When you run by root, you cannot change `-rw-r--r-- 1 root root` to `-rw-r--r-- 1 usernotexistinyourmachine apache`.Normally,if username not exist,will be replaced by userid like `1001`.But if owner is `root`, cannot change to `1001` – kittygirl Jan 11 '19 at 10:12
  • @kittygirl Uh? Why not? Of course `notexistuser` has to exist. If you request to make a file owned by a user but you give an invalid user name, then the request is rejected, this is the correct behavior. Restoring won't invent a user ID for you, you have to restore the user account before restoring the files. – Gilles 'SO- stop being evil' Jan 11 '19 at 10:49
  • @Gilles,there's no any notice that request is rejected.And, ONLY `notexistuser` keep the same,`group` and `permission` changed.Which means if you don't know exactly every user and group of a large `permissions.facl`,error may happen. – kittygirl Jan 11 '19 at 11:38
4

I'm not aware of anything "off the shelf" that would do this. Here's a starter script for you, though, that will handle basic permissions. It does not handle ACLs of any description - but your Question explicitly excludes those. (It will also fail on pathological filenames - those starting with whitespace, or containing non-printable characters.)

Save the permissions

find * -depth -exec stat --format '%a %u %g %n' {} + >/tmp/save-the-list

Restore the permissions

while read PERMS OWNER GROUP FILE
do
    chmod "$PERMS" "$FILE"
    chown "${OWNER}:${GROUP}" "$FILE"
done </tmp/save-the-list
roaima
  • 107,089
  • 14
  • 139
  • 261
  • do you mean ACL will also fail on pathological filenames? – kittygirl Oct 02 '18 at 16:07
  • @kittygirl I didn't include any processing of ACLs in the scriptlet because the OP had explicitly excluded them from the requirements. You can add what you like, bearing in mind that the code isn't particularly robust (see the comment describing pathological filenames). – roaima Oct 02 '18 at 17:29
  • I found a problem:cannot find `.htaccess`,`gitignore`... – kittygirl Jan 10 '19 at 14:20
0
#!/bin/bash
# prepare files
home="/home/exchange"
cd $home
>acl
echo "#!/bin/bash">recovery_acl.sh
echo "cd $home">>recovery_acl.sh
f='./'
# create acl file sorted by dir_level
for i in `seq 0 15`;do
  find . -mindepth $i -maxdepth $i -type d -exec getfacl {} +|grep -E '*UTS|file:'>>acl
done
sed -i 's/default\:user/\-dm\ u/g' acl
sed -i 's/default\:group/\-dm\ g/g' acl
sed -i 's/user/\-m\ u/g' acl
sed -i 's/group/\-m\ g/g' acl
sed -i 's/\#\ file\:\ /\.\//g' acl
sed -i 's,\\,\\\\,g' acl

while IFS='' read -r line ; do
  # grep dir name
  if echo "$line" | grep -q "$f" ; then
    dir="$line"
    continue
  fi
  echo setfacl $line '"'$dir'"'>>recovery_acl.sh
  # grep non def acl (for files)
  if echo "$line" | grep -q '\-m' ; then
    echo setfacl $line '"'$dir'"'/*>>recovery_acl.sh
  fi
done < "acl"

sed -i "s/\\\134/\\\\\\\134/g" recovery_acl.sh
sed -i "s/\\\040/\\\\ /g" recovery_acl.sh

This bash script get acl only dirs (in my case files acls = dir(parent) acl ) After execution of script, will creating another "recovery_acl.sh".

While recovering Errors like "No such file or directory" means that dir is empty or dirname has two/more spaces together.