rsynced files not getting proper ACL

I use rsync (rsync-3.0.6-5.el6_0.1.x86_64 on Scientific Linux 6) to transfer files from a VFAT disk to an NFS mounted ext3 file system. I have ACLs set up on the ext3 system and all works as expected when i.e. creating new files or dirs (through the NFS mount, via command line or Nautilus). But when rsync-ing or cp-ing, ACLs are not created for the copied files on the ext3 partition.

The background is the VFAT is from a camera, intermittently mounted, and does not create acls for dirs or files. Is there a way to rsync (or even copy) that lets i.e. the default ACL rules apply ACLs to rsync-ed or cp-ed files and dirs?


Solution 1:

After a little help from my friends and much gnashing of teeth, I figured this out. Of course, the answer was in the man pages.

The problem stems from the fact that (from the acl man page): "modification of the file permission bits result in the modification of the associated ACL entries" and vice versa. Because without the proper flag, rsync uses the source permissions this changes the ACLs on the target.

The solution in rsync is to use the --chmod option. From the rsync man page (in the --perms section):

To give new files the destination-default permissions (while leaving existing files unchanged), make sure that the --perms option is off and use --chmod=ugo=rwX (which ensures that all non-masked bits get enabled).

However, the rights one would want to use depend on the intended target rights. As an example, in my case, the source perms were 700, with no ACL. The destination sub-directory had a default ACL as follows: d:u:user1:rwx,d:u:user2:rwx,u:user1:rwx,u:user2:rwx,d:m:rwx,m:rwx. That is, it has two named users, an explicit mask, as well as identical defaults. This equates to 770.

When using rsync (or cp-ing), the source permission of 700 override the default ACL mask, setting it to --- instead of rwx.

Since this uses case needs "user" and "group" but no "other" source permissions, I used the following flag in rsync: --chmod=ug=rwx. The letters after the first equal sign indicate that the following perms apply to the u(ser) and g(roup). The letters following the second equal sign indicate the permissions those users receive. This makes rsync set the perms on the target to 770.

The actual command is: rsync -av --chmod=ug=rwX /<source> /<destination>

A few things to note. First, rsync permission behaviour depends upon the version on the receiving end. Check man pages for the definitive answer. Second, the order of flags is important: -a, -A and so on can, in fact, be used but MUST come before the --chmod flag.

Lastly, I see no similar flag available for cp making rsync the only game in town for syncing files AND applying default ACLs on the target to files with different source permissions.

Solution 2:

How exactly are you calling rsync? Since your source doesn't support ACLs you should almost certainly NOT be passing any options that set instruct rsync to copy permissions.

So don't use -a, -o, -g, or -A.