| 1 | This patch implements an idiom where two -o options cause rsync |
| 2 | to try to set the owner information even if we're not running as |
| 3 | UID 0. Similarly, two -g options cause rsync to try to set all |
| 4 | groups, even if they weren't returned by getgroups(). E.g.: |
| 5 | |
| 6 | rsync -avoogg host:/from/ /to/ |
| 7 | |
| 8 | --- orig/compat.c 2005-03-09 18:53:55 |
| 9 | +++ compat.c 2005-03-11 11:25:46 |
| 10 | @@ -28,11 +28,14 @@ |
| 11 | int remote_protocol = 0; |
| 12 | |
| 13 | extern int verbose; |
| 14 | +extern int am_root; |
| 15 | extern int am_server; |
| 16 | extern int am_sender; |
| 17 | extern int inplace; |
| 18 | extern int fuzzy_basis; |
| 19 | extern int read_batch; |
| 20 | +extern int preserve_uid; |
| 21 | +extern int preserve_gid; |
| 22 | extern int checksum_seed; |
| 23 | extern int basis_dir_cnt; |
| 24 | extern int protocol_version; |
| 25 | @@ -106,4 +109,11 @@ void setup_protocol(int f_out,int f_in) |
| 26 | } else { |
| 27 | checksum_seed = read_int(f_in); |
| 28 | } |
| 29 | + |
| 30 | + if (am_root) { |
| 31 | + if (preserve_uid) |
| 32 | + preserve_uid = 2; |
| 33 | + if (preserve_gid) |
| 34 | + preserve_gid = 2; |
| 35 | + } |
| 36 | } |
| 37 | --- orig/options.c 2005-03-24 16:41:46 |
| 38 | +++ options.c 2004-09-09 01:59:08 |
| 39 | @@ -404,8 +404,8 @@ static struct poptOption long_options[] |
| 40 | {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 }, |
| 41 | {"copy-unsafe-links",0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 }, |
| 42 | {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 }, |
| 43 | - {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 }, |
| 44 | - {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 }, |
| 45 | + {"owner", 'o', POPT_ARG_NONE, 0, 'o', 0, 0 }, |
| 46 | + {"group", 'g', POPT_ARG_NONE, 0, 'g', 0, 0 }, |
| 47 | {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 }, |
| 48 | {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 }, |
| 49 | {"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 2, 0, 0 }, |
| 50 | @@ -747,6 +747,14 @@ int parse_arguments(int *argc, const cha |
| 51 | usage(FINFO); |
| 52 | exit_cleanup(0); |
| 53 | |
| 54 | + case 'o': |
| 55 | + preserve_uid++; |
| 56 | + break; |
| 57 | + |
| 58 | + case 'g': |
| 59 | + preserve_gid++; |
| 60 | + break; |
| 61 | + |
| 62 | case 'v': |
| 63 | verbose++; |
| 64 | break; |
| 65 | @@ -949,8 +957,8 @@ int parse_arguments(int *argc, const cha |
| 66 | #endif |
| 67 | preserve_perms = 1; |
| 68 | preserve_times = 1; |
| 69 | - preserve_gid = 1; |
| 70 | - preserve_uid = 1; |
| 71 | + preserve_uid |= 1; |
| 72 | + preserve_gid |= 1; |
| 73 | preserve_devices = 1; |
| 74 | } |
| 75 | |
| 76 | @@ -1264,10 +1272,16 @@ void server_options(char **args,int *arg |
| 77 | |
| 78 | if (preserve_hard_links) |
| 79 | argstr[x++] = 'H'; |
| 80 | - if (preserve_uid) |
| 81 | + if (preserve_uid) { |
| 82 | argstr[x++] = 'o'; |
| 83 | - if (preserve_gid) |
| 84 | + if (preserve_uid > 1) |
| 85 | + argstr[x++] = 'o'; |
| 86 | + } |
| 87 | + if (preserve_gid) { |
| 88 | argstr[x++] = 'g'; |
| 89 | + if (preserve_gid > 1) |
| 90 | + argstr[x++] = 'g'; |
| 91 | + } |
| 92 | if (preserve_devices) |
| 93 | argstr[x++] = 'D'; |
| 94 | if (preserve_times) |
| 95 | --- orig/rsync.c 2005-03-16 02:19:30 |
| 96 | +++ rsync.c 2005-02-01 10:46:04 |
| 97 | @@ -27,7 +27,6 @@ extern int dry_run; |
| 98 | extern int daemon_log_format_has_i; |
| 99 | extern int preserve_times; |
| 100 | extern int omit_dir_times; |
| 101 | -extern int am_root; |
| 102 | extern int am_server; |
| 103 | extern int am_sender; |
| 104 | extern int am_generator; |
| 105 | @@ -81,7 +80,7 @@ int set_perms(char *fname,struct file_st |
| 106 | updated = 1; |
| 107 | } |
| 108 | |
| 109 | - change_uid = am_root && preserve_uid && st->st_uid != file->uid; |
| 110 | + change_uid = preserve_uid > 1 && st->st_uid != file->uid; |
| 111 | change_gid = preserve_gid && file->gid != GID_NONE |
| 112 | && st->st_gid != file->gid; |
| 113 | #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK |
| 114 | --- orig/uidlist.c 2005-02-14 00:53:44 |
| 115 | +++ uidlist.c 2004-09-09 01:59:08 |
| 116 | @@ -35,7 +35,6 @@ extern int verbose; |
| 117 | extern int preserve_uid; |
| 118 | extern int preserve_gid; |
| 119 | extern int numeric_ids; |
| 120 | -extern int am_root; |
| 121 | |
| 122 | struct idlist { |
| 123 | struct idlist *next; |
| 124 | @@ -177,7 +176,7 @@ static struct idlist *recv_add_gid(int i |
| 125 | int id2 = name ? map_gid(id, name) : id; |
| 126 | struct idlist *node; |
| 127 | |
| 128 | - if (!am_root && !is_in_group(id2)) |
| 129 | + if (preserve_gid < 2 && !is_in_group(id2)) |
| 130 | id2 = GID_NONE; |
| 131 | node = add_to_list(&gidlist, id, name, id2); |
| 132 | |
| 133 | @@ -339,11 +338,11 @@ void recv_uid_list(int f, struct file_li |
| 134 | |
| 135 | /* now convert the uid/gid of all files in the list to the mapped |
| 136 | * uid/gid */ |
| 137 | - if (am_root && preserve_uid && !numeric_ids) { |
| 138 | + if (preserve_uid > 1 && !numeric_ids) { |
| 139 | for (i = 0; i < flist->count; i++) |
| 140 | flist->files[i]->uid = match_uid(flist->files[i]->uid); |
| 141 | } |
| 142 | - if (preserve_gid && (!am_root || !numeric_ids)) { |
| 143 | + if (preserve_gid && (preserve_gid < 2 || !numeric_ids)) { |
| 144 | for (i = 0; i < flist->count; i++) |
| 145 | flist->files[i]->gid = match_gid(flist->files[i]->gid); |
| 146 | } |