mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-10 16:03:48 -04:00
Send the uid/gid 0 name since not all systems use 0 for root.
This commit is contained in:
5
compat.c
5
compat.c
@@ -73,6 +73,7 @@ int want_xattr_optim = 0;
|
||||
int proper_seed_order = 0;
|
||||
int inplace_partial = 0;
|
||||
int do_negotiated_strings = 0;
|
||||
int xmit_id0_names = 0;
|
||||
|
||||
/* These index values are for the file-list's extra-attribute array. */
|
||||
int pathname_ndx, depth_ndx, atimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
|
||||
@@ -109,6 +110,7 @@ struct name_num_obj valid_compressions = {
|
||||
#define CF_CHKSUM_SEED_FIX (1<<5)
|
||||
#define CF_INPLACE_PARTIAL_DIR (1<<6)
|
||||
#define CF_VARINT_FLIST_FLAGS (1<<7)
|
||||
#define CF_ID0_NAMES (1<<8)
|
||||
|
||||
static const char *client_info;
|
||||
|
||||
@@ -694,6 +696,8 @@ void setup_protocol(int f_out,int f_in)
|
||||
compat_flags |= CF_CHKSUM_SEED_FIX;
|
||||
if (local_server || strchr(client_info, 'I') != NULL)
|
||||
compat_flags |= CF_INPLACE_PARTIAL_DIR;
|
||||
if (local_server || strchr(client_info, 'u') != NULL)
|
||||
compat_flags |= CF_ID0_NAMES;
|
||||
if (local_server || strchr(client_info, 'v') != NULL) {
|
||||
do_negotiated_strings = 1;
|
||||
compat_flags |= CF_VARINT_FLIST_FLAGS;
|
||||
@@ -714,6 +718,7 @@ void setup_protocol(int f_out,int f_in)
|
||||
want_xattr_optim = protocol_version >= 31 && !(compat_flags & CF_AVOID_XATTR_OPTIM);
|
||||
proper_seed_order = compat_flags & CF_CHKSUM_SEED_FIX ? 1 : 0;
|
||||
xfer_flags_as_varint = compat_flags & CF_VARINT_FLIST_FLAGS ? 1 : 0;
|
||||
xmit_id0_names = compat_flags & CF_ID0_NAMES ? 1 : 0;
|
||||
if (am_sender) {
|
||||
receiver_symlink_times = am_server
|
||||
? strchr(client_info, 'L') != NULL
|
||||
|
||||
2
flist.c
2
flist.c
@@ -2412,7 +2412,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
file_old_total += flist->used;
|
||||
|
||||
if (numeric_ids <= 0 && !inc_recurse)
|
||||
send_id_list(f);
|
||||
send_id_lists(f);
|
||||
|
||||
/* send the io_error flag */
|
||||
if (protocol_version < 30)
|
||||
|
||||
@@ -2608,6 +2608,7 @@ void server_options(char **args, int *argc_p)
|
||||
eFlags[x++] = 'C'; /* support checksum seed order fix */
|
||||
eFlags[x++] = 'I'; /* support inplace_partial behavior */
|
||||
eFlags[x++] = 'v'; /* use varint for flist & compat flags; negotiate checksum */
|
||||
eFlags[x++] = 'u'; /* include name of uid 0 & gid 0 in the id map */
|
||||
/* NOTE: Avoid using 'V' -- it was the high bit of a write_byte() that became write_varint(). */
|
||||
#undef eFlags
|
||||
}
|
||||
|
||||
75
uidlist.c
75
uidlist.c
@@ -33,6 +33,7 @@ extern int preserve_uid;
|
||||
extern int preserve_gid;
|
||||
extern int preserve_acls;
|
||||
extern int numeric_ids;
|
||||
extern int xmit_id0_names;
|
||||
extern gid_t our_gid;
|
||||
extern char *usermap;
|
||||
extern char *groupmap;
|
||||
@@ -295,9 +296,6 @@ const char *add_uid(uid_t uid)
|
||||
struct idlist *node;
|
||||
union name_or_id noiu;
|
||||
|
||||
if (uid == 0) /* don't map root */
|
||||
return NULL;
|
||||
|
||||
for (list = uidlist; list; list = list->next) {
|
||||
if (list->id == uid)
|
||||
return NULL;
|
||||
@@ -315,9 +313,6 @@ const char *add_gid(gid_t gid)
|
||||
struct idlist *node;
|
||||
union name_or_id noiu;
|
||||
|
||||
if (gid == 0) /* don't map root */
|
||||
return NULL;
|
||||
|
||||
for (list = gidlist; list; list = list->next) {
|
||||
if (list->id == gid)
|
||||
return NULL;
|
||||
@@ -328,40 +323,43 @@ const char *add_gid(gid_t gid)
|
||||
return node->u.name;
|
||||
}
|
||||
|
||||
/* send a complete uid/gid mapping to the peer */
|
||||
void send_id_list(int f)
|
||||
static void send_one_name(int f, id_t id, const char *name)
|
||||
{
|
||||
int len = strlen(name);
|
||||
if (len > 255) /* Impossible? */
|
||||
len = 255;
|
||||
|
||||
write_varint30(f, id);
|
||||
write_byte(f, len);
|
||||
write_buf(f, name, len);
|
||||
}
|
||||
|
||||
static void send_one_list(int f, struct idlist *idlist, int usernames)
|
||||
{
|
||||
struct idlist *list;
|
||||
|
||||
if (preserve_uid || preserve_acls) {
|
||||
int len;
|
||||
/* we send sequences of uid/byte-length/name */
|
||||
for (list = uidlist; list; list = list->next) {
|
||||
if (!list->u.name)
|
||||
continue;
|
||||
len = strlen(list->u.name);
|
||||
write_varint30(f, list->id);
|
||||
write_byte(f, len);
|
||||
write_buf(f, list->u.name, len);
|
||||
}
|
||||
|
||||
/* terminate the uid list with a 0 uid. We explicitly exclude
|
||||
* 0 from the list */
|
||||
write_varint30(f, 0);
|
||||
/* we send sequences of id/byte-len/name */
|
||||
for (list = idlist; list; list = list->next) {
|
||||
if (list->id && list->u.name)
|
||||
send_one_name(f, list->id, list->u.name);
|
||||
}
|
||||
|
||||
if (preserve_gid || preserve_acls) {
|
||||
int len;
|
||||
for (list = gidlist; list; list = list->next) {
|
||||
if (!list->u.name)
|
||||
continue;
|
||||
len = strlen(list->u.name);
|
||||
write_varint30(f, list->id);
|
||||
write_byte(f, len);
|
||||
write_buf(f, list->u.name, len);
|
||||
}
|
||||
/* Terminate the uid list with 0 (which was excluded above).
|
||||
* A modern rsync also sends the name of id 0. */
|
||||
if (xmit_id0_names)
|
||||
send_one_name(f, 0, usernames ? uid_to_user(0) : gid_to_group(0));
|
||||
else
|
||||
write_varint30(f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* send a complete uid/gid mapping to the peer */
|
||||
void send_id_lists(int f)
|
||||
{
|
||||
if (preserve_uid || preserve_acls)
|
||||
send_one_list(f, uidlist, 1);
|
||||
|
||||
if (preserve_gid || preserve_acls)
|
||||
send_one_list(f, gidlist, 0);
|
||||
}
|
||||
|
||||
uid_t recv_user_name(int f, uid_t uid)
|
||||
@@ -405,12 +403,16 @@ void recv_id_list(int f, struct file_list *flist)
|
||||
/* read the uid list */
|
||||
while ((id = read_varint30(f)) != 0)
|
||||
recv_user_name(f, id);
|
||||
if (xmit_id0_names)
|
||||
recv_user_name(f, 0);
|
||||
}
|
||||
|
||||
if ((preserve_gid || preserve_acls) && numeric_ids <= 0) {
|
||||
/* read the gid list */
|
||||
while ((id = read_varint30(f)) != 0)
|
||||
recv_group_name(f, id, NULL);
|
||||
if (xmit_id0_names)
|
||||
recv_group_name(f, 0, NULL);
|
||||
}
|
||||
|
||||
/* Now convert all the uids/gids from sender values to our values. */
|
||||
@@ -502,8 +504,9 @@ void parse_name_map(char *map, BOOL usernames)
|
||||
*--cp = '\0'; /* replace comma */
|
||||
}
|
||||
|
||||
/* The 0 user/group doesn't get its name sent, so add it explicitly. */
|
||||
recv_add_id(idlist_ptr, *idmap_ptr, 0, numeric_ids ? NULL : usernames ? uid_to_user(0) : gid_to_group(0));
|
||||
/* If the sender isn't going to xmit the id0 name, we assume it's "root". */
|
||||
if (!xmit_id0_names)
|
||||
recv_add_id(idlist_ptr, *idmap_ptr, 0, numeric_ids ? NULL : "root");
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETGROUPLIST
|
||||
|
||||
Reference in New Issue
Block a user