22

I need to rsync a directory to a remote server so that all files belonging to user X and group Y on the source (local) machine are mapped to user W and group Z on the destination (remote) machine. If possible by using ssh as the transport, but if I need to use the rsync daemon it's fine as well.

Is there a way to do that? I'm looking for a way to establish an arbitrary user/group map, such as

local user X => remote user W
local group Y => remote group Z
... and as many of these as needed.

This should be a pretty common use case, isn't it? E.g. I have files on my local computer where my username is X, and I need to upload them to a web server where they need to belong to a given user which doesn't have either the same name or the same UID as my user on my personal computer.

I can't find that on rsync's man page...

Linux on both local and remote machine (Ubuntu local, CentOS remote)

Command I tried:

rsync -avz /path/to/local [email protected]:/path/to/remote
1
  • 1
    Please always include your OS. Solutions very often depend on the Operating System being used. Are you using Windows, Linux, Unix, OSX, BSD? Which version?
    – terdon
    Nov 7, 2013 at 17:42

5 Answers 5

26

Rsync version 3.1.0 introduced the --usermap and --groupmap options precisely for that purpose. See the man page.

2
  • This is good to know. There's definitely a use case scenario for this. For example, I've got two Icinga servers and I need to do a one-way sync of the config files from master to slave. But icinga on the master is a different uid than icinga on the slave. So, good to know rsync can handle this. Nov 7, 2014 at 17:35
  • Version notes: Ubuntu v16.04 has v3.1.1, CentOS 7 has v3.1.2, but CentOS 6 has v3.0.6. This works great for newer distros.
    – jimp
    Dec 4, 2018 at 22:03
8

Last version (at least 3.1.1) of rsync allows you to specify the "remote ownership":

--usermap=tom:www-data

Changes tom ownership to www-data (aka PHP/Nginx). If you are using Mac as the client, use brew to upgrade to the last version. And on your server, download archives sources, then "make" it!

2
  • for me it works as --chown=tom:www-data May 21, 2018 at 14:18
  • 1
    @FedericoGalli's comment above is wrong and will leave you with incorrect permissions. --chown simply overwrites every files user/group with tom/www-data. The original question specifically asks for only mapping of user X to W and group Y to Z, which would make files owned by, say, X:ftp become owned by W:ftp, whereas the comment would result in tom:www-data for a file previously owned by tom:ftp. --usermap and --groupmap are the correct options.
    – Torque
    May 17, 2023 at 11:23
1

If you want to change ownership of files to arbitrary users, you'll first need to be root on the destination box.

I don't think there is such a feature integrated by rsync, but you can achive it by running a find after doing your rsync.

Maybe, a command like this will do the trick : For example, translate from UID 1000 => 505 and UID 1001 => 700 :

find /your/rsynced/path -user 1000 -exec chown 505 {} \;
find /your/rsynced/path -user 1001 -exec chown 700 {} \;

If you have many users, you may consider using a loop with a mapping, in your predilection language.

Have fun.

6
  • Ok so there just isn't a way to have rsync do that. Astonishing, it seemed to me such an obvious need.
    – matteo
    Nov 7, 2013 at 19:35
  • 1
    @matteo careful if you use this. If there is a user with id 1000 or 1001 on the remote machine there may be files that are legitimately owned by them in the remote locations and chowning them could cause problems.
    – terdon
    Nov 7, 2013 at 19:42
  • @terdon how would there be a user without a name on the remote machine? (because if the ID is shown instead of the name when files are listed, it means the user doesn't have a name, right?)
    – matteo
    Nov 8, 2013 at 14:14
  • 1
    @matteo no, every user has a user id as well as a name. In most Debian based systems (and probably others) the first, default user is user 1000. Try running id on your machine to see. Therefore, if you use the IDs like this, you are assuming that there is no user with the same ID on the remote machine and that is likely not true.
    – terdon
    Nov 8, 2013 at 15:49
  • in my case there's no user with UID 1000 on the server, at least it is not listed in /etc/passwd. Which was what I guessed because when I list files with "ls -la", files belonging to 1000 (which were the result of rsync -avz from my local machine where user 1000 is my default user "teo") show up with "1000" as the owner. If there was a user with that id, and its name was, say "Someone", then the owner of the files would be shown as "Someone" in the output of ls, right? Anyway that's a useful caveat to take into account, thanks.
    – matteo
    Nov 8, 2013 at 19:22
0

As mentioned in Federico's and Torque's comments, there is a simpler way for a typical use case, which might be useful to OP, but is generally helpful any way. The accepted answer maps only the specified user and group, leaving any others as-is, which may not be desired. You would need to add a fallback mapping or first (as below) or check the ownerships of everything on the sending side.

--usermap='X:W,*:root' --groupmap='Y:Z,*:root'

If you just need all sent files to match a specific user & group on the destination, then use this:

--chown=USER:GROUP

Obviously, replace USER & GROUP with the actual destination's ones.

-1

I am not sure I understand, to connect over ssh you need to provide a username. That username will be user W on the remote machine who belongs to group Z. Therefore, everything will be transferred exactly as you want it to be:

rsync /path/to/local [email protected]/path/to/remote

EDIT in answer to the OP's comment.

If you want to do this user mapping and not lose permissions settings, don't use -a. First, run the rsync with [email protected] to get the right username. Then, instead of -a which will cause you to preserve ownership, specify the options manually. From man rsync:

    -a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)
    -r, --recursive             recurse into directories
    -l, --links                 copy symlinks as symlinks
    -p, --perms                 preserve permissions
    -t, --times                 preserve modification times
    -g, --group                 preserve group
    -o, --owner                 preserve owner (super-user only)
    -D                          same as --devices --specials

So, -a activates all of the above options but you don't want to preserve the group or owner. This command should do what you want:

rsync -rlptDvz /path/to/local [email protected]:/path/to/remote

Since you are now logging in as mywww and no longer preserving owner/group information, the copies made by rsync will belong to the mywww user.

9
  • No, I do rsync -avz /path/to/local [email protected]:/path/to/remote. My question is, how do I get files belonging to user "x" on my local machine to be remapped to user "w" on the server? On my computer, my files belong to "teo". On the server there is not even a user called "teo", I need the user to be the one that apache uses, say "mywww"; and the same for the group. By default, rsync will try to preserve the owner as "teo", and since there's no such user, it will preserve the UID, resulting in files belonging to user "1000" which is a nonexisting user on the server
    – matteo
    Nov 7, 2013 at 18:01
  • Btw, at the same time I need to preserve file permissions which it already does as per the -a option. I mean, any solution that will make me loose the ability to preserve file permissions (i.e. a 777 file remain a 777 and a 600 remain a 600) won't do the trick
    – matteo
    Nov 7, 2013 at 18:04
  • @matteo that's because -a enables the preserve owner and group options. See my updated answer.
    – terdon
    Nov 7, 2013 at 18:18
  • 1
    @matteo please explain what you actually need when you ask questions. That way we don't waste time providing incomplete answers. Next time, remember to i) include the actual commands you used (rsync does not preserve anything by default, your use of -a did that) ii) clearly explain all constraints that you have, you just mentioned a single user until your last comment and iii) mention your OS. Anyway, the way to do this with rsync would be to copy one set of files as mywww@remote and the next set as root@remote.
    – terdon
    Nov 7, 2013 at 19:41
  • 2
    @matteo what was really not clear was that you were using -a which preserves ownership. The examples you gave suggested you only needed to do this for one user. Anyway, I would recommend you use rsync, just make a list of the different files you want to copy for each user and run multiple rsyncs connecting to the remote machine with the relevant username. That will be simpler and safer.
    – terdon
    Nov 8, 2013 at 16:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .