Ownership

Wayne Davison wayned at samba.org
Thu Sep 9 02:10:54 GMT 2004


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..
-------------- next part --------------
--- 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);
 	}


More information about the rsync mailing list