On Wed, Sep 08, 2004 at 04:52:51PM -0400, Paul Haas wrote:
> I can think of 4 usefull modes:
> 1                    The default, don't try to chown().
> 2 --owner            If rsync thinks it is root, then try to chown()
> 3 --owner-whining    Always try to chown() and whine if it doesn't work.
> 4 --owner-no-whining Always try to chown(), don't whine if it doesn't work.

Here's a patch that adds mode 3 to the two existing modes (leaving mode
4 unimplemented for now).  It forces the user to specify -oo to perform
chowing even when not root (-ao is not enough), and to specify -gg to
try to preserve all groups when not root (even if the group wasn't
returned by the getgroups() call).  For example:

    rsync -avoogg /src/ host:/dest

This only works if both sides have this patch applied (otherwise the
normal -o and -g behavior would apply).

Thoughts?

..wayne..
--- compat.c    21 Jul 2004 23:59:22 -0000      1.24
+++ compat.c    9 Sep 2004 01:59:08 -0000
@@ -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;
+       }
 }
--- options.c   8 Sep 2004 07:33:06 -0000       1.179
+++ options.c   9 Sep 2004 01:59:08 -0000
@@ -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)
--- rsync.c     7 Sep 2004 20:37:36 -0000       1.148
+++ rsync.c     9 Sep 2004 01:59:08 -0000
@@ -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) {
--- uidlist.c   28 Apr 2004 17:31:31 -0000      1.24
+++ uidlist.c   9 Sep 2004 01:59:08 -0000
@@ -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);
        }
-- 
To unsubscribe or change options: http://lists.samba.org/mailman/listinfo/rsync
Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html

Reply via email to