From 6c4bd5abdb8cd8b0218e53123dc3a534eff1191e Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sat, 18 Sep 2004 01:57:47 +0000 Subject: [PATCH] One possible solution to let users who can chown files (but aren't UID 0) preserve owner and group info. --- owner-group-mod.diff | 143 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 owner-group-mod.diff diff --git a/owner-group-mod.diff b/owner-group-mod.diff new file mode 100644 index 0000000..19f1e7c --- /dev/null +++ b/owner-group-mod.diff @@ -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, ©_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); + } -- 2.34.1