-
- datum_size = sys_lgetxattr(fname, name, NULL, 0);
-@@ -315,6 +325,12 @@ void receive_xattr(struct file_struct *f
- memmove(ptr, ptr + UPRE_LEN, rxa->name_len);
+ rxas->name = ptr + datum_len;
+ memcpy(rxas->name, name, name_len);
+@@ -293,20 +314,23 @@ void receive_xattr(struct file_struct *f
+ rsync_xa *rxa;
+ size_t name_len = read_int(f);
+ size_t datum_len = read_int(f);
++ size_t extra_len = am_root < 0 ? FPRE_LEN + RPRE_LEN : RPRE_LEN;
+ if (name_len + datum_len < name_len)
+ out_of_memory("receive_xattr"); /* overflow */
+-#ifndef HAVE_LINUX_XATTRS
+- if (name_len + datum_len + RPRE_LEN < RPRE_LEN)
++ if (name_len + datum_len + extra_len < extra_len)
+ out_of_memory("receive_xattr"); /* overflow */
+-#endif
+- ptr = new_array(char, name_len + datum_len + RPRE_LEN);
++ ptr = new_array(char, name_len + datum_len + extra_len);
+ if (!ptr)
+ out_of_memory("receive_xattr");
+- name = ptr + datum_len + RPRE_LEN;
++ name = ptr + datum_len + extra_len;
+ read_buf(f, name, name_len);
+ read_buf(f, ptr, datum_len);
+ #ifdef HAVE_LINUX_XATTRS
+ /* Non-root can only save the user namespace. */
++ if (am_root < 0 && strncmp(name, USER_PREFIX, UPRE_LEN) != 0) {
++ name -= FPRE_LEN;
++ memcpy(name, FAKE_PREFIX, FPRE_LEN);
++ } else
+ if (!am_root && strncmp(name, USER_PREFIX, UPRE_LEN) != 0) {
+ free(ptr);
+ continue;
+@@ -323,6 +347,11 @@ void receive_xattr(struct file_struct *f
+ memcpy(name, RSYNC_PREFIX, RPRE_LEN);