Why is rsync getting “permission denied” errors on Mac OS X when ACLs are set for the correct user

access-control-listosx-snow-leopardrsync

I'm transitioning away from an old tool that initiates an rsync (copying from a local path to a remote path w/SSH hostkeys) via a web form (completely behind a firewall w/multiple authentication layers, not that that's an excuse) hosted on Mac OS X 10.6 Snow Leopard Server. To work around the fact that rsync is run by _www, but the files are owned by someuser (plus the SSH hostkeys are for someuser), the original author made a copy of the rsync binary w/permissions of 4755 & someuser as the owner (so, anyone who runs that copy of rsync has it run as the someuser user). A dirty hack, for sure, but it works (and it was written before Mac OS X even had support for ACLs, so it's at least slightly understandable, though it's still atrocious from a security standpoint).

As my first step in moving away from this solution, I've changed the permissions of those files from 777 (owned by someuser) to 755 (still owned by someuser), then set ACLs for _www to have full access to those files, as follows:

chmod -R +a "_www allow read,write,delete,add_file,add_subdirectory,file_inherit,directory_inherit" /path/to/directory

Unfortunately, while still using the same rsync binary with the set-user-ID-on-execution bit set for someuser, rsync now throws the following error:

building file list ... rsync: link_stat "/path/to/directory/subdir/." failed: Permission denied (13)
done

sent 332 bytes  received 20 bytes  704.00 bytes/sec
total size is 0  speedup is 0.00
rsync error: some files could not be transferred (code 23) at /SourceCache/rsync/rsync-30/rsync/main.c(717)

If I check the permissions for that directory, they seem correct:

$ ls -ael /path/to/directory/
total 0
drwxr-x---+  3 someuser  admin  102 Jun 23 19:00 .
 0: user:_www allow list,add_file,delete,add_subdirectory,file_inherit,directory_inherit
drwxr-xr-x   8 someuser  admin  272 Jun 23 18:57 ..
drwxr-xr-x+ 17 someuser  admin  578 Jun 23 17:15 subdir
 0: user:_www allow list,add_file,delete,add_subdirectory,file_inherit,directory_inherit

The same is true of a file in the directory:

$ ls -ael /path/to/directory/subdir/file.txt 
-rwxr-xr-x+ 1 someuser  admin  107 Jun 23 17:15 subdir/file.txt
 0: user:_www allow read,write,delete,append

What would cause this permissions error since the files are still owned by the user which the rsync binary runs, plus the _www user should have full ACLs for the directory & files?

Update: It seems like it's an ACL issue as running sudo -u _www ls -ael /path/to/directory/ results in "permission denied" errors as well:

ls: .: Permission denied
ls: ..: Permission denied
ls: subdir: Permission denied`

So, what's wrong with the ACLs I've set?

Best Answer

In Server Admin.app, I enabled the "Show system accounts in the users & groups browser" preference, then went to File Sharing and browsed to /path/to/directory/ (w/"Volumes" & "Browse" selected in the toolbar) I added a "Custom" ACL (no "Administration", but all "Read", "Write", and "Applies to") for the '_www' user and propagated the permissions.

This resulted in the following when running ls as the '_www' user:

$ sudo -u _www ls -ale /path/to/directory
total 0
drwxr-x---+  3 someuser  admin  102 Jun 23 19:00 .
 0: user:_www allow list,add_file,search,delete,add_subdirectory,delete_child,readattr,writeattr,readextattr,writeextattr,readsecurity,file_inherit,directory_inherit
drwxr-xr-x   8 someuser  admin  272 Jun 23 18:57 ..
drwxr-xr-x+ 17 someuser  admin  578 Jun 23 17:15 subdir
 0: user:_www inherited allow list,add_file,search,delete,add_subdirectory,delete_child,readattr,writeattr,readextattr,writeextattr,readsecurity,file_inherit,directory_inherit

So, that resolved the issue. By looking at the ACLs that were set, it looks like it was probably the missing 'search' access which was causing the failures (maybe some of the others, although those appear to only be related to extended attributes).