One possible solution to let users who can chown files (but aren't
authorWayne Davison <wayned@samba.org>
Sat, 18 Sep 2004 01:57:47 +0000 (01:57 +0000)
committerWayne Davison <wayned@samba.org>
Sat, 18 Sep 2004 01:57:47 +0000 (01:57 +0000)
UID 0) preserve owner and group info.

owner-group-mod.diff [new file with mode: 0644]

diff --git a/owner-group-mod.diff b/owner-group-mod.diff
new file mode 100644 (file)
index 0000000..19f1e7c
--- /dev/null
@@ -0,0 +1,143 @@
+This patch implements an idiom where two -o options cause rsync
+to try to set the owner information even if we're not running as
+UID 0.  Similarly, two -g options cause rsync to try to set all
+groups, even if they weren't returned by getgroups().  E.g.:
+
+    rsync -avoogg host:/from/ /to/
+
+--- orig/compat.c      2004-07-21 23:59:35
++++ compat.c   2004-09-09 01:59:08
+@@ -28,8 +28,11 @@
+ int remote_protocol = 0;
+ extern int verbose;
++extern int am_root;
+ extern int am_server;
+ extern int am_sender;
++extern int preserve_uid;
++extern int preserve_gid;
+ extern int read_batch;
+ extern int checksum_seed;
+ extern int protocol_version;
+@@ -81,4 +84,11 @@ void setup_protocol(int f_out,int f_in)
+       } else {
+               checksum_seed = read_int(f_in);
+       }
++
++      if (am_root) {
++              if (preserve_uid)
++                      preserve_uid = 2;
++              if (preserve_gid)
++                      preserve_gid = 2;
++      }
+ }
+--- orig/options.c     2004-09-18 01:49:33
++++ options.c  2004-09-09 01:59:08
+@@ -358,8 +358,8 @@ static struct poptOption long_options[] 
+   {"no-whole-file",    0,  POPT_ARG_VAL,    &whole_file, 0, 0, 0 },
+   {"copy-unsafe-links", 0, POPT_ARG_NONE,   &copy_unsafe_links, 0, 0, 0 },
+   {"perms",           'p', POPT_ARG_NONE,   &preserve_perms, 0, 0, 0 },
+-  {"owner",           'o', POPT_ARG_NONE,   &preserve_uid, 0, 0, 0 },
+-  {"group",           'g', POPT_ARG_NONE,   &preserve_gid, 0, 0, 0 },
++  {"owner",           'o', POPT_ARG_NONE,   0,               'o', 0, 0 },
++  {"group",           'g', POPT_ARG_NONE,   0,               'g', 0, 0 },
+   {"devices",         'D', POPT_ARG_NONE,   &preserve_devices, 0, 0, 0 },
+   {"times",           't', POPT_ARG_NONE,   &preserve_times, 0, 0, 0 },
+   {"checksum",        'c', POPT_ARG_NONE,   &always_checksum, 0, 0, 0 },
+@@ -568,6 +568,14 @@ int parse_arguments(int *argc, const cha
+                       usage(FINFO);
+                       exit_cleanup(0);
++              case 'o':
++                      preserve_uid++;
++                      break;
++
++              case 'g':
++                      preserve_gid++;
++                      break;
++
+               case 'v':
+                       verbose++;
+                       break;
+@@ -707,8 +715,8 @@ int parse_arguments(int *argc, const cha
+ #endif
+               preserve_perms = 1;
+               preserve_times = 1;
+-              preserve_gid = 1;
+-              preserve_uid = 1;
++              preserve_uid |= 1;
++              preserve_gid |= 1;
+               preserve_devices = 1;
+       }
+@@ -934,10 +942,16 @@ void server_options(char **args,int *arg
+       if (preserve_hard_links)
+               argstr[x++] = 'H';
+-      if (preserve_uid)
++      if (preserve_uid) {
+               argstr[x++] = 'o';
+-      if (preserve_gid)
++              if (preserve_uid > 1)
++                      argstr[x++] = 'o';
++      }
++      if (preserve_gid) {
+               argstr[x++] = 'g';
++              if (preserve_gid > 1)
++                      argstr[x++] = 'g';
++      }
+       if (preserve_devices)
+               argstr[x++] = 'D';
+       if (preserve_times)
+--- orig/rsync.c       2004-09-07 21:45:30
++++ rsync.c    2004-09-09 01:59:08
+@@ -25,7 +25,6 @@
+ extern int verbose;
+ extern int dry_run;
+ extern int preserve_times;
+-extern int am_root;
+ extern int am_sender;
+ extern int am_generator;
+ extern int preserve_uid;
+@@ -158,7 +157,7 @@ int set_perms(char *fname,struct file_st
+               updated = 1;
+       }
+-      change_uid = am_root && preserve_uid && st->st_uid != file->uid;
++      change_uid = preserve_uid > 1 && st->st_uid != file->uid;
+       change_gid = preserve_gid && file->gid != GID_NONE
+               && st->st_gid != file->gid;
+       if (change_uid || change_gid) {
+--- orig/uidlist.c     2004-04-29 19:37:25
++++ uidlist.c  2004-09-09 01:59:08
+@@ -35,7 +35,6 @@ extern int verbose;
+ extern int preserve_uid;
+ extern int preserve_gid;
+ extern int numeric_ids;
+-extern int am_root;
+ struct idlist {
+       struct idlist *next;
+@@ -177,7 +176,7 @@ static struct idlist *recv_add_gid(int i
+       int id2 = name ? map_gid(id, name) : id;
+       struct idlist *node;
+-      if (!am_root && !is_in_group(id2))
++      if (preserve_gid < 2 && !is_in_group(id2))
+               id2 = GID_NONE;
+       node = add_to_list(&gidlist, id, name, id2);
+@@ -339,11 +338,11 @@ void recv_uid_list(int f, struct file_li
+       /* now convert the uid/gid of all files in the list to the mapped
+        * uid/gid */
+-      if (am_root && preserve_uid && !numeric_ids) {
++      if (preserve_uid > 1 && !numeric_ids) {
+               for (i = 0; i < flist->count; i++)
+                       flist->files[i]->uid = match_uid(flist->files[i]->uid);
+       }
+-      if (preserve_gid && (!am_root || !numeric_ids)) {
++      if (preserve_gid && (preserve_gid < 2 || !numeric_ids)) {
+               for (i = 0; i < flist->count; i++)
+                       flist->files[i]->gid = match_gid(flist->files[i]->gid);
+       }