]> git.ipfire.org Git - thirdparty/rsync.git/blob - xattrs.c
Join some lines.
[thirdparty/rsync.git] / xattrs.c
1 /*
2 * Extended Attribute support for rsync.
3 * Written by Jay Fenlason, vaguely based on the ACLs patch.
4 *
5 * Copyright (C) 2004 Red Hat, Inc.
6 * Copyright (C) 2006-2015 Wayne Davison
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, visit the http://fsf.org website.
20 */
21
22 #include "rsync.h"
23 #include "ifuncs.h"
24 #include "inums.h"
25 #include "lib/sysxattrs.h"
26
27 #ifdef SUPPORT_XATTRS
28
29 extern int dry_run;
30 extern int am_root;
31 extern int am_sender;
32 extern int am_generator;
33 extern int read_only;
34 extern int list_only;
35 extern int preserve_xattrs;
36 extern int preserve_links;
37 extern int preserve_devices;
38 extern int preserve_specials;
39 extern int checksum_seed;
40
41 #define RSYNC_XAL_INITIAL 5
42 #define RSYNC_XAL_LIST_INITIAL 100
43
44 #define MAX_FULL_DATUM 32
45
46 #define HAS_PREFIX(str, prfx) (*(str) == *(prfx) \
47 && strncmp(str, prfx, sizeof (prfx) - 1) == 0)
48
49 #define XATTR_ABBREV(x) ((size_t)((x).name - (x).datum) < (x).datum_len)
50
51 #define XSTATE_ABBREV 1
52 #define XSTATE_DONE 2
53 #define XSTATE_TODO 3
54
55 #define USER_PREFIX "user."
56 #define UPRE_LEN ((int)sizeof USER_PREFIX - 1)
57 #define SYSTEM_PREFIX "system."
58 #define SPRE_LEN ((int)sizeof SYSTEM_PREFIX - 1)
59
60 #ifdef HAVE_LINUX_XATTRS
61 #define MIGHT_NEED_RPRE (am_root < 0)
62 #define RSYNC_PREFIX USER_PREFIX "rsync."
63 #else
64 #define MIGHT_NEED_RPRE am_root
65 #define RSYNC_PREFIX "rsync."
66 #endif
67 #define RPRE_LEN ((int)sizeof RSYNC_PREFIX - 1)
68
69 #define XSTAT_SUFFIX "stat"
70 #define XSTAT_ATTR RSYNC_PREFIX "%" XSTAT_SUFFIX
71 #define XACC_ACL_SUFFIX "aacl"
72 #define XACC_ACL_ATTR RSYNC_PREFIX "%" XACC_ACL_SUFFIX
73 #define XDEF_ACL_SUFFIX "dacl"
74 #define XDEF_ACL_ATTR RSYNC_PREFIX "%" XDEF_ACL_SUFFIX
75
76 typedef struct {
77 char *datum, *name;
78 size_t datum_len, name_len;
79 int num;
80 } rsync_xa;
81
82 struct _rsync_xa_list;
83
84 typedef struct _rsync_xa_list_ref {
85 struct _rsync_xa_list_ref *next;
86 int ndx;
87 } rsync_xa_list_ref;
88
89 typedef struct _rsync_xa_list {
90 int ndx;
91 int64 key;
92 item_list xa_items;
93 } rsync_xa_list;
94
95 static size_t namebuf_len = 0;
96 static char *namebuf = NULL;
97
98 static const rsync_xa_list empty_xa_list = {
99 .xa_items = EMPTY_ITEM_LIST,
100 };
101 static const item_list empty_xattr = EMPTY_ITEM_LIST;
102 static item_list rsync_xal_l = EMPTY_ITEM_LIST;
103 static struct hashtable *rsync_xal_h = NULL;
104
105 static size_t prior_xattr_count = (size_t)-1;
106
107 /* ------------------------------------------------------------------------- */
108
109 static void rsync_xal_free(item_list *xalp)
110 {
111 size_t i;
112 rsync_xa *rxas = xalp->items;
113
114 if (!xalp->malloced)
115 return;
116
117 for (i = 0; i < xalp->count; i++) {
118 free(rxas[i].datum);
119 /*free(rxas[i].name);*/
120 }
121 free(xalp->items);
122 }
123
124 void free_xattr(stat_x *sxp)
125 {
126 if (!sxp->xattr)
127 return;
128 rsync_xal_free(sxp->xattr);
129 free(sxp->xattr);
130 sxp->xattr = NULL;
131 }
132
133 static int rsync_xal_compare_names(const void *x1, const void *x2)
134 {
135 const rsync_xa *xa1 = x1;
136 const rsync_xa *xa2 = x2;
137 return strcmp(xa1->name, xa2->name);
138 }
139
140 static ssize_t get_xattr_names(const char *fname)
141 {
142 ssize_t list_len;
143 int64 arg;
144
145 if (!namebuf) {
146 namebuf_len = 1024;
147 namebuf = new_array(char, namebuf_len);
148 if (!namebuf)
149 out_of_memory("get_xattr_names");
150 }
151
152 while (1) {
153 /* The length returned includes all the '\0' terminators. */
154 list_len = sys_llistxattr(fname, namebuf, namebuf_len);
155 if (list_len >= 0) {
156 if ((size_t)list_len <= namebuf_len)
157 break;
158 } else if (errno == ENOTSUP)
159 return 0;
160 else if (errno != ERANGE) {
161 arg = namebuf_len;
162 got_error:
163 rsyserr(FERROR_XFER, errno,
164 "get_xattr_names: llistxattr(%s,%s) failed",
165 full_fname(fname), big_num(arg));
166 return -1;
167 }
168 list_len = sys_llistxattr(fname, NULL, 0);
169 if (list_len < 0) {
170 arg = 0;
171 goto got_error;
172 }
173 if (namebuf_len)
174 free(namebuf);
175 namebuf_len = list_len + 1024;
176 namebuf = new_array(char, namebuf_len);
177 if (!namebuf)
178 out_of_memory("get_xattr_names");
179 }
180
181 return list_len;
182 }
183
184 /* On entry, the *len_ptr parameter contains the size of the extra space we
185 * should allocate when we create a buffer for the data. On exit, it contains
186 * the length of the datum. */
187 static char *get_xattr_data(const char *fname, const char *name, size_t *len_ptr,
188 int no_missing_error)
189 {
190 size_t datum_len = sys_lgetxattr(fname, name, NULL, 0);
191 size_t extra_len = *len_ptr;
192 char *ptr;
193
194 *len_ptr = datum_len;
195
196 if (datum_len == (size_t)-1) {
197 if (errno == ENOTSUP || no_missing_error)
198 return NULL;
199 rsyserr(FERROR_XFER, errno,
200 "get_xattr_data: lgetxattr(%s,\"%s\",0) failed",
201 full_fname(fname), name);
202 return NULL;
203 }
204
205 if (!datum_len && !extra_len)
206 extra_len = 1; /* request non-zero amount of memory */
207 if (datum_len + extra_len < datum_len)
208 overflow_exit("get_xattr_data");
209 if (!(ptr = new_array(char, datum_len + extra_len)))
210 out_of_memory("get_xattr_data");
211
212 if (datum_len) {
213 size_t len = sys_lgetxattr(fname, name, ptr, datum_len);
214 if (len != datum_len) {
215 if (len == (size_t)-1) {
216 rsyserr(FERROR_XFER, errno,
217 "get_xattr_data: lgetxattr(%s,\"%s\",%ld) failed",
218 full_fname(fname), name, (long)datum_len);
219 } else {
220 rprintf(FERROR_XFER,
221 "get_xattr_data: lgetxattr(%s,\"%s\",%ld) returned %ld\n",
222 full_fname(fname), name,
223 (long)datum_len, (long)len);
224 }
225 free(ptr);
226 return NULL;
227 }
228 }
229
230 return ptr;
231 }
232
233 static int rsync_xal_get(const char *fname, item_list *xalp)
234 {
235 ssize_t list_len, name_len;
236 size_t datum_len, name_offset;
237 char *name, *ptr;
238 #ifdef HAVE_LINUX_XATTRS
239 int user_only = am_sender ? 0 : !am_root;
240 #endif
241 rsync_xa *rxa;
242 int count;
243
244 /* This puts the name list into the "namebuf" buffer. */
245 if ((list_len = get_xattr_names(fname)) < 0)
246 return -1;
247
248 for (name = namebuf; list_len > 0; name += name_len) {
249 name_len = strlen(name) + 1;
250 list_len -= name_len;
251
252 #ifdef HAVE_LINUX_XATTRS
253 /* Choose between ignoring the system namespace or (non-root) ignoring any non-user namespace. */
254 if (user_only ? !HAS_PREFIX(name, USER_PREFIX) : HAS_PREFIX(name, SYSTEM_PREFIX))
255 continue;
256 #endif
257
258 /* No rsync.%FOO attributes are copied w/o 2 -X options. */
259 if (name_len > RPRE_LEN && name[RPRE_LEN] == '%' && HAS_PREFIX(name, RSYNC_PREFIX)) {
260 if ((am_sender && preserve_xattrs < 2)
261 || (am_root < 0
262 && (strcmp(name+RPRE_LEN+1, XSTAT_SUFFIX) == 0
263 || strcmp(name+RPRE_LEN+1, XACC_ACL_SUFFIX) == 0
264 || strcmp(name+RPRE_LEN+1, XDEF_ACL_SUFFIX) == 0)))
265 continue;
266 }
267
268 datum_len = name_len; /* Pass extra size to get_xattr_data() */
269 if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
270 return -1;
271
272 if (datum_len > MAX_FULL_DATUM) {
273 /* For large datums, we store a flag and a checksum. */
274 name_offset = 1 + MAX_DIGEST_LEN;
275 sum_init(-1, checksum_seed);
276 sum_update(ptr, datum_len);
277 free(ptr);
278
279 if (!(ptr = new_array(char, name_offset + name_len)))
280 out_of_memory("rsync_xal_get");
281 *ptr = XSTATE_ABBREV;
282 sum_end(ptr + 1);
283 } else
284 name_offset = datum_len;
285
286 rxa = EXPAND_ITEM_LIST(xalp, rsync_xa, RSYNC_XAL_INITIAL);
287 rxa->name = ptr + name_offset;
288 memcpy(rxa->name, name, name_len);
289 rxa->datum = ptr;
290 rxa->name_len = name_len;
291 rxa->datum_len = datum_len;
292 }
293 count = xalp->count;
294 rxa = xalp->items;
295 if (count > 1)
296 qsort(rxa, count, sizeof (rsync_xa), rsync_xal_compare_names);
297 for (rxa += count-1; count; count--, rxa--)
298 rxa->num = count;
299 return 0;
300 }
301
302 /* Read the xattr(s) for this filename. */
303 int get_xattr(const char *fname, stat_x *sxp)
304 {
305 sxp->xattr = new(item_list);
306 *sxp->xattr = empty_xattr;
307
308 if (S_ISREG(sxp->st.st_mode) || S_ISDIR(sxp->st.st_mode)) {
309 /* Everyone supports this. */
310 } else if (S_ISLNK(sxp->st.st_mode)) {
311 #ifndef NO_SYMLINK_XATTRS
312 if (!preserve_links)
313 #endif
314 return 0;
315 } else if (IS_SPECIAL(sxp->st.st_mode)) {
316 #ifndef NO_SPECIAL_XATTRS
317 if (!preserve_specials)
318 #endif
319 return 0;
320 } else if (IS_DEVICE(sxp->st.st_mode)) {
321 #ifndef NO_DEVICE_XATTRS
322 if (!preserve_devices)
323 #endif
324 return 0;
325 } else if (IS_MISSING_FILE(sxp->st))
326 return 0;
327
328 if (rsync_xal_get(fname, sxp->xattr) < 0) {
329 free_xattr(sxp);
330 return -1;
331 }
332 return 0;
333 }
334
335 int copy_xattrs(const char *source, const char *dest)
336 {
337 ssize_t list_len, name_len;
338 size_t datum_len;
339 char *name, *ptr;
340 #ifdef HAVE_LINUX_XATTRS
341 int user_only = am_sender ? 0 : am_root <= 0;
342 #endif
343
344 /* This puts the name list into the "namebuf" buffer. */
345 if ((list_len = get_xattr_names(source)) < 0)
346 return -1;
347
348 for (name = namebuf; list_len > 0; name += name_len) {
349 name_len = strlen(name) + 1;
350 list_len -= name_len;
351
352 #ifdef HAVE_LINUX_XATTRS
353 /* Choose between ignoring the system namespace or (non-root) ignoring any non-user namespace. */
354 if (user_only ? !HAS_PREFIX(name, USER_PREFIX) : HAS_PREFIX(name, SYSTEM_PREFIX))
355 continue;
356 #endif
357
358 datum_len = 0;
359 if (!(ptr = get_xattr_data(source, name, &datum_len, 0)))
360 return -1;
361 if (sys_lsetxattr(dest, name, ptr, datum_len) < 0) {
362 int save_errno = errno ? errno : EINVAL;
363 rsyserr(FERROR_XFER, errno,
364 "copy_xattrs: lsetxattr(%s,\"%s\") failed",
365 full_fname(dest), name);
366 errno = save_errno;
367 return -1;
368 }
369 free(ptr);
370 }
371
372 return 0;
373 }
374
375 static int64 xattr_lookup_hash(const item_list *xalp)
376 {
377 const rsync_xa *rxas = xalp->items;
378 size_t i;
379 int64 key = hashlittle(&xalp->count, sizeof xalp->count);
380
381 for (i = 0; i < xalp->count; i++) {
382 key += hashlittle(rxas[i].name, rxas[i].name_len);
383 if (rxas[i].datum_len > MAX_FULL_DATUM)
384 key += hashlittle(rxas[i].datum, MAX_DIGEST_LEN);
385 else
386 key += hashlittle(rxas[i].datum, rxas[i].datum_len);
387 }
388
389 if (key == 0) {
390 /* This is very unlikely, but we should never
391 * return 0 as hashtable_find() doesn't like it. */
392 return 1;
393 }
394
395 return key;
396 }
397
398 static int find_matching_xattr(const item_list *xalp)
399 {
400 const struct ht_int64_node *node;
401 const rsync_xa_list_ref *ref;
402 int64 key;
403
404 if (rsync_xal_h == NULL)
405 return -1;
406
407 key = xattr_lookup_hash(xalp);
408
409 node = hashtable_find(rsync_xal_h, key, 0);
410 if (node == NULL)
411 return -1;
412
413 if (node->data == NULL)
414 return -1;
415
416 for (ref = node->data; ref != NULL; ref = ref->next) {
417 const rsync_xa_list *ptr = rsync_xal_l.items;
418 const rsync_xa *rxas1;
419 const rsync_xa *rxas2 = xalp->items;
420 size_t j;
421
422 ptr += ref->ndx;
423 rxas1 = ptr->xa_items.items;
424
425 /* Wrong number of elements? */
426 if (ptr->xa_items.count != xalp->count)
427 continue;
428 /* any elements different? */
429 for (j = 0; j < xalp->count; j++) {
430 if (rxas1[j].name_len != rxas2[j].name_len
431 || rxas1[j].datum_len != rxas2[j].datum_len
432 || strcmp(rxas1[j].name, rxas2[j].name))
433 break;
434 if (rxas1[j].datum_len > MAX_FULL_DATUM) {
435 if (memcmp(rxas1[j].datum + 1,
436 rxas2[j].datum + 1,
437 MAX_DIGEST_LEN) != 0)
438 break;
439 } else {
440 if (memcmp(rxas1[j].datum, rxas2[j].datum,
441 rxas2[j].datum_len))
442 break;
443 }
444 }
445 /* no differences found. This is The One! */
446 if (j == xalp->count)
447 return ref->ndx;
448 }
449
450 return -1;
451 }
452
453 /* Store *xalp on the end of rsync_xal_l */
454 static int rsync_xal_store(item_list *xalp)
455 {
456 struct ht_int64_node *node;
457 int ndx = rsync_xal_l.count; /* pre-incremented count */
458 rsync_xa_list *new_list = EXPAND_ITEM_LIST(&rsync_xal_l, rsync_xa_list, RSYNC_XAL_LIST_INITIAL);
459 rsync_xa_list_ref *new_ref;
460 /* Since the following call starts a new list, we know it will hold the
461 * entire initial-count, not just enough space for one new item. */
462 *new_list = empty_xa_list;
463 (void)EXPAND_ITEM_LIST(&new_list->xa_items, rsync_xa, xalp->count);
464 memcpy(new_list->xa_items.items, xalp->items, xalp->count * sizeof (rsync_xa));
465 new_list->xa_items.count = xalp->count;
466 xalp->count = 0;
467
468 new_list->ndx = ndx;
469 new_list->key = xattr_lookup_hash(&new_list->xa_items);
470
471 if (rsync_xal_h == NULL)
472 rsync_xal_h = hashtable_create(512, 1);
473 if (rsync_xal_h == NULL)
474 out_of_memory("rsync_xal_h hashtable_create()");
475
476 node = hashtable_find(rsync_xal_h, new_list->key, 1);
477 if (node == NULL)
478 out_of_memory("rsync_xal_h hashtable_find()");
479
480 new_ref = new0(rsync_xa_list_ref);
481 if (new_ref == NULL)
482 out_of_memory("new0(rsync_xa_list_ref)");
483
484 new_ref->ndx = ndx;
485
486 if (node->data != NULL) {
487 rsync_xa_list_ref *ref = node->data;
488
489 while (ref != NULL) {
490 if (ref->next != NULL) {
491 ref = ref->next;
492 continue;
493 }
494
495 ref->next = new_ref;
496 break;
497 }
498 } else
499 node->data = new_ref;
500
501 return ndx;
502 }
503
504 /* Send the make_xattr()-generated xattr list for this flist entry. */
505 int send_xattr(int f, stat_x *sxp)
506 {
507 int ndx = find_matching_xattr(sxp->xattr);
508
509 /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
510 write_varint(f, ndx + 1);
511
512 if (ndx < 0) {
513 rsync_xa *rxa;
514 int count = sxp->xattr->count;
515 write_varint(f, count);
516 for (rxa = sxp->xattr->items; count--; rxa++) {
517 size_t name_len = rxa->name_len;
518 const char *name = rxa->name;
519 /* Strip the rsync prefix from disguised namespaces. */
520 if (name_len > RPRE_LEN
521 #ifdef HAVE_LINUX_XATTRS
522 && am_root < 0
523 #endif
524 && name[RPRE_LEN] != '%' && HAS_PREFIX(name, RSYNC_PREFIX)) {
525 name += RPRE_LEN;
526 name_len -= RPRE_LEN;
527 }
528 #ifndef HAVE_LINUX_XATTRS
529 else {
530 /* Put everything else in the user namespace. */
531 name_len += UPRE_LEN;
532 }
533 #endif
534 write_varint(f, name_len);
535 write_varint(f, rxa->datum_len);
536 #ifndef HAVE_LINUX_XATTRS
537 if (name_len > rxa->name_len) {
538 write_buf(f, USER_PREFIX, UPRE_LEN);
539 name_len -= UPRE_LEN;
540 }
541 #endif
542 write_buf(f, name, name_len);
543 if (rxa->datum_len > MAX_FULL_DATUM)
544 write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
545 else
546 write_bigbuf(f, rxa->datum, rxa->datum_len);
547 }
548 ndx = rsync_xal_store(sxp->xattr); /* adds item to rsync_xal_l */
549 }
550
551 return ndx;
552 }
553
554 /* Return a flag indicating if we need to change a file's xattrs. If
555 * "find_all" is specified, also mark any abbreviated xattrs that we
556 * need so that send_xattr_request() can tell the sender about them. */
557 int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
558 {
559 const rsync_xa_list *glst = rsync_xal_l.items;
560 const item_list *lst;
561 rsync_xa *snd_rxa, *rec_rxa;
562 int snd_cnt, rec_cnt;
563 int cmp, same, xattrs_equal = 1;
564
565 if (sxp && XATTR_READY(*sxp)) {
566 rec_rxa = sxp->xattr->items;
567 rec_cnt = sxp->xattr->count;
568 } else {
569 rec_rxa = NULL;
570 rec_cnt = 0;
571 }
572
573 if (F_XATTR(file) >= 0) {
574 glst += F_XATTR(file);
575 lst = &glst->xa_items;
576 } else
577 lst = &empty_xattr;
578
579 snd_rxa = lst->items;
580 snd_cnt = lst->count;
581
582 /* If the count of the sender's xattrs is different from our
583 * (receiver's) xattrs, the lists are not the same. */
584 if (snd_cnt != rec_cnt) {
585 if (!find_all)
586 return 1;
587 xattrs_equal = 0;
588 }
589
590 while (snd_cnt) {
591 cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
592 if (cmp > 0)
593 same = 0;
594 else if (snd_rxa->datum_len > MAX_FULL_DATUM) {
595 same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
596 && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
597 MAX_DIGEST_LEN) == 0;
598 /* Flag unrequested items that we need. */
599 if (!same && find_all && snd_rxa->datum[0] == XSTATE_ABBREV)
600 snd_rxa->datum[0] = XSTATE_TODO;
601 } else {
602 same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
603 && memcmp(snd_rxa->datum, rec_rxa->datum,
604 snd_rxa->datum_len) == 0;
605 }
606 if (!same) {
607 if (!find_all)
608 return 1;
609 xattrs_equal = 0;
610 }
611
612 if (cmp <= 0) {
613 snd_rxa++;
614 snd_cnt--;
615 }
616 if (cmp >= 0) {
617 rec_rxa++;
618 rec_cnt--;
619 }
620 }
621
622 if (rec_cnt)
623 xattrs_equal = 0;
624
625 return !xattrs_equal;
626 }
627
628 /* When called by the generator (with a NULL fname), this tells the sender
629 * all the abbreviated xattr values we need. When called by the sender
630 * (with a non-NULL fname), we send all the extra xattr data it needs.
631 * The generator may also call with f_out < 0 to just change all the
632 * XSTATE_ABBREV states into XSTATE_DONE. */
633 void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
634 {
635 const rsync_xa_list *glst = rsync_xal_l.items;
636 const item_list *lst;
637 int cnt, prior_req = 0;
638 rsync_xa *rxa;
639
640 glst += F_XATTR(file);
641 lst = &glst->xa_items;
642
643 for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) {
644 if (rxa->datum_len <= MAX_FULL_DATUM)
645 continue;
646 switch (rxa->datum[0]) {
647 case XSTATE_ABBREV:
648 /* Items left abbreviated matched the sender's checksum, so
649 * the receiver will cache the local data for future use. */
650 if (am_generator)
651 rxa->datum[0] = XSTATE_DONE;
652 continue;
653 case XSTATE_TODO:
654 assert(f_out >= 0);
655 break;
656 default:
657 continue;
658 }
659
660 /* Flag that we handled this abbreviated item. */
661 rxa->datum[0] = XSTATE_DONE;
662
663 write_varint(f_out, rxa->num - prior_req);
664 prior_req = rxa->num;
665
666 if (fname) {
667 size_t len = 0;
668 char *ptr;
669
670 /* Re-read the long datum. */
671 if (!(ptr = get_xattr_data(fname, rxa->name, &len, 0))) {
672 rprintf(FERROR_XFER, "failed to re-read xattr %s for %s\n", rxa->name, fname);
673 write_varint(f_out, 0);
674 continue;
675 }
676
677 write_varint(f_out, len); /* length might have changed! */
678 write_bigbuf(f_out, ptr, len);
679 free(ptr);
680 }
681 }
682
683 if (f_out >= 0)
684 write_byte(f_out, 0); /* end the list */
685 }
686
687 /* When called by the sender, read the request from the generator and mark
688 * any needed xattrs with a flag that lets us know they need to be sent to
689 * the receiver. When called by the receiver, reads the sent data and
690 * stores it in place of its checksum. */
691 int recv_xattr_request(struct file_struct *file, int f_in)
692 {
693 const rsync_xa_list *glst = rsync_xal_l.items;
694 const item_list *lst;
695 char *old_datum, *name;
696 rsync_xa *rxa;
697 int rel_pos, cnt, num, got_xattr_data = 0;
698
699 if (F_XATTR(file) < 0) {
700 rprintf(FERROR, "recv_xattr_request: internal data error!\n");
701 exit_cleanup(RERR_PROTOCOL);
702 }
703 glst += F_XATTR(file);
704 lst = &glst->xa_items;
705
706 cnt = lst->count;
707 rxa = lst->items;
708 num = 0;
709 while ((rel_pos = read_varint(f_in)) != 0) {
710 num += rel_pos;
711 if (am_sender) {
712 /* The sender-related num values are only in order on the sender.
713 * We use that order here to scan foward or backward as needed. */
714 if (rel_pos < 0) {
715 while (cnt < (int)lst->count && rxa->num > num) {
716 rxa--;
717 cnt++;
718 }
719 } else {
720 while (cnt > 1 && rxa->num < num) {
721 rxa++;
722 cnt--;
723 }
724 }
725 } else {
726 int j;
727 /* The receiving side has no known num order, so we just scan
728 * forward (w/wrap) and hope that the next value is near by. */
729 for (j = lst->count; j > 1 && rxa->num != num; j--) {
730 if (--cnt)
731 rxa++;
732 else {
733 cnt = lst->count;
734 rxa = lst->items;
735 }
736 }
737 }
738 if (!cnt || rxa->num != num) {
739 rprintf(FERROR, "[%s] could not find xattr #%d for %s\n",
740 who_am_i(), num, f_name(file, NULL));
741 exit_cleanup(RERR_PROTOCOL);
742 }
743 if (!XATTR_ABBREV(*rxa) || rxa->datum[0] != XSTATE_ABBREV) {
744 rprintf(FERROR, "[%s] internal abbrev error on %s (%s, len=%ld)!\n",
745 who_am_i(), f_name(file, NULL), rxa->name, (long)rxa->datum_len);
746 exit_cleanup(RERR_PROTOCOL);
747 }
748
749 if (am_sender) {
750 rxa->datum[0] = XSTATE_TODO;
751 continue;
752 }
753
754 old_datum = rxa->datum;
755 rxa->datum_len = read_varint(f_in);
756
757 if (rxa->name_len + rxa->datum_len < rxa->name_len)
758 overflow_exit("recv_xattr_request");
759 rxa->datum = new_array(char, rxa->datum_len + rxa->name_len);
760 if (!rxa->datum)
761 out_of_memory("recv_xattr_request");
762 name = rxa->datum + rxa->datum_len;
763 memcpy(name, rxa->name, rxa->name_len);
764 rxa->name = name;
765 free(old_datum);
766 read_buf(f_in, rxa->datum, rxa->datum_len);
767 got_xattr_data = 1;
768 }
769
770 return got_xattr_data;
771 }
772
773 /* ------------------------------------------------------------------------- */
774
775 /* receive and build the rsync_xattr_lists */
776 void receive_xattr(int f, struct file_struct *file)
777 {
778 static item_list temp_xattr = EMPTY_ITEM_LIST;
779 int count, num;
780 #ifdef HAVE_LINUX_XATTRS
781 int need_sort = 0;
782 #else
783 int need_sort = 1;
784 #endif
785 int ndx = read_varint(f);
786
787 if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
788 rprintf(FERROR, "receive_xattr: xa index %d out of"
789 " range for %s\n", ndx, f_name(file, NULL));
790 exit_cleanup(RERR_STREAMIO);
791 }
792
793 if (ndx != 0) {
794 F_XATTR(file) = ndx - 1;
795 return;
796 }
797
798 if ((count = read_varint(f)) != 0) {
799 (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
800 temp_xattr.count = 0;
801 }
802
803 for (num = 1; num <= count; num++) {
804 char *ptr, *name;
805 rsync_xa *rxa;
806 size_t name_len = read_varint(f);
807 size_t datum_len = read_varint(f);
808 size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
809 size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
810 if ((dget_len + extra_len < dget_len)
811 || (dget_len + extra_len + name_len < dget_len))
812 overflow_exit("receive_xattr");
813 ptr = new_array(char, dget_len + extra_len + name_len);
814 if (!ptr)
815 out_of_memory("receive_xattr");
816 name = ptr + dget_len + extra_len;
817 read_buf(f, name, name_len);
818 if (dget_len == datum_len)
819 read_buf(f, ptr, dget_len);
820 else {
821 *ptr = XSTATE_ABBREV;
822 read_buf(f, ptr + 1, MAX_DIGEST_LEN);
823 }
824 #ifdef HAVE_LINUX_XATTRS
825 /* Non-root can only save the user namespace. */
826 if (am_root <= 0 && !HAS_PREFIX(name, USER_PREFIX)) {
827 if (!am_root) {
828 free(ptr);
829 continue;
830 }
831 name -= RPRE_LEN;
832 name_len += RPRE_LEN;
833 memcpy(name, RSYNC_PREFIX, RPRE_LEN);
834 need_sort = 1;
835 }
836 #else
837 /* This OS only has a user namespace, so we either
838 * strip the user prefix, or we put a non-user
839 * namespace inside our rsync hierarchy. */
840 if (HAS_PREFIX(name, USER_PREFIX)) {
841 name += UPRE_LEN;
842 name_len -= UPRE_LEN;
843 } else if (am_root) {
844 name -= RPRE_LEN;
845 name_len += RPRE_LEN;
846 memcpy(name, RSYNC_PREFIX, RPRE_LEN);
847 } else {
848 free(ptr);
849 continue;
850 }
851 #endif
852 /* No rsync.%FOO attributes are copied w/o 2 -X options. */
853 if (preserve_xattrs < 2 && name_len > RPRE_LEN
854 && name[RPRE_LEN] == '%' && HAS_PREFIX(name, RSYNC_PREFIX)) {
855 free(ptr);
856 continue;
857 }
858
859 rxa = EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, 1);
860 rxa->name = name;
861 rxa->datum = ptr;
862 rxa->name_len = name_len;
863 rxa->datum_len = datum_len;
864 rxa->num = num;
865 }
866
867 if (need_sort && count > 1)
868 qsort(temp_xattr.items, count, sizeof (rsync_xa), rsync_xal_compare_names);
869
870 ndx = rsync_xal_store(&temp_xattr); /* adds item to rsync_xal_l */
871
872 F_XATTR(file) = ndx;
873 }
874
875 /* Turn the xattr data in stat_x into cached xattr data, setting the index
876 * values in the file struct. */
877 void cache_tmp_xattr(struct file_struct *file, stat_x *sxp)
878 {
879 int ndx;
880
881 if (!sxp->xattr)
882 return;
883
884 if (prior_xattr_count == (size_t)-1)
885 prior_xattr_count = rsync_xal_l.count;
886 ndx = find_matching_xattr(sxp->xattr);
887 if (ndx < 0)
888 rsync_xal_store(sxp->xattr); /* adds item to rsync_xal_l */
889
890 F_XATTR(file) = ndx;
891 }
892
893 void uncache_tmp_xattrs(void)
894 {
895 if (prior_xattr_count != (size_t)-1) {
896 rsync_xa_list *xa_list_item = rsync_xal_l.items;
897 rsync_xa_list *xa_list_start = xa_list_item + prior_xattr_count;
898 xa_list_item += rsync_xal_l.count;
899 rsync_xal_l.count = prior_xattr_count;
900 while (xa_list_item-- > xa_list_start) {
901 struct ht_int64_node *node;
902 rsync_xa_list_ref *ref;
903
904 rsync_xal_free(&xa_list_item->xa_items);
905
906 if (rsync_xal_h == NULL)
907 continue;
908
909 node = hashtable_find(rsync_xal_h, xa_list_item->key, 0);
910 if (node == NULL)
911 continue;
912
913 if (node->data == NULL)
914 continue;
915
916 ref = node->data;
917 if (xa_list_item->ndx == ref->ndx) {
918 /* xa_list_item is the first in the list. */
919 node->data = ref->next;
920 free(ref);
921 continue;
922 }
923
924 while (ref != NULL) {
925 if (ref->next == NULL) {
926 ref = NULL;
927 break;
928 }
929 if (xa_list_item->ndx == ref->next->ndx) {
930 ref->next = ref->next->next;
931 free(ref);
932 break;
933 }
934 ref = ref->next;
935 }
936 }
937 prior_xattr_count = (size_t)-1;
938 }
939 }
940
941 static int rsync_xal_set(const char *fname, item_list *xalp,
942 const char *fnamecmp, stat_x *sxp)
943 {
944 rsync_xa *rxas = xalp->items;
945 ssize_t list_len;
946 size_t i, len;
947 char *name, *ptr, sum[MAX_DIGEST_LEN];
948 #ifdef HAVE_LINUX_XATTRS
949 int user_only = am_root <= 0;
950 #endif
951 size_t name_len;
952 int ret = 0;
953
954 /* This puts the current name list into the "namebuf" buffer. */
955 if ((list_len = get_xattr_names(fname)) < 0)
956 return -1;
957
958 for (i = 0; i < xalp->count; i++) {
959 name = rxas[i].name;
960
961 if (XATTR_ABBREV(rxas[i])) {
962 /* See if the fnamecmp version is identical. */
963 len = name_len = rxas[i].name_len;
964 if ((ptr = get_xattr_data(fnamecmp, name, &len, 1)) == NULL) {
965 still_abbrev:
966 if (am_generator)
967 continue;
968 rprintf(FERROR, "Missing abbreviated xattr value, %s, for %s\n",
969 rxas[i].name, full_fname(fname));
970 ret = -1;
971 continue;
972 }
973 if (len != rxas[i].datum_len) {
974 free(ptr);
975 goto still_abbrev;
976 }
977
978 sum_init(-1, checksum_seed);
979 sum_update(ptr, len);
980 sum_end(sum);
981 if (memcmp(sum, rxas[i].datum + 1, MAX_DIGEST_LEN) != 0) {
982 free(ptr);
983 goto still_abbrev;
984 }
985
986 if (fname == fnamecmp)
987 ; /* Value is already set when identical */
988 else if (sys_lsetxattr(fname, name, ptr, len) < 0) {
989 rsyserr(FERROR_XFER, errno,
990 "rsync_xal_set: lsetxattr(%s,\"%s\") failed",
991 full_fname(fname), name);
992 ret = -1;
993 } else /* make sure caller sets mtime */
994 sxp->st.st_mtime = (time_t)-1;
995
996 if (am_generator) { /* generator items stay abbreviated */
997 free(ptr);
998 continue;
999 }
1000
1001 memcpy(ptr + len, name, name_len);
1002 free(rxas[i].datum);
1003
1004 rxas[i].name = name = ptr + len;
1005 rxas[i].datum = ptr;
1006 continue;
1007 }
1008
1009 if (sys_lsetxattr(fname, name, rxas[i].datum, rxas[i].datum_len) < 0) {
1010 rsyserr(FERROR_XFER, errno,
1011 "rsync_xal_set: lsetxattr(%s,\"%s\") failed",
1012 full_fname(fname), name);
1013 ret = -1;
1014 } else /* make sure caller sets mtime */
1015 sxp->st.st_mtime = (time_t)-1;
1016 }
1017
1018 /* Remove any extraneous names. */
1019 for (name = namebuf; list_len > 0; name += name_len) {
1020 name_len = strlen(name) + 1;
1021 list_len -= name_len;
1022
1023 #ifdef HAVE_LINUX_XATTRS
1024 /* Choose between ignoring the system namespace or (non-root) ignoring any non-user namespace. */
1025 if (user_only ? !HAS_PREFIX(name, USER_PREFIX) : HAS_PREFIX(name, SYSTEM_PREFIX))
1026 continue;
1027 #endif
1028 if (am_root < 0 && name_len > RPRE_LEN && name[RPRE_LEN] == '%' && strcmp(name, XSTAT_ATTR) == 0)
1029 continue;
1030
1031 for (i = 0; i < xalp->count; i++) {
1032 if (strcmp(name, rxas[i].name) == 0)
1033 break;
1034 }
1035 if (i == xalp->count) {
1036 if (sys_lremovexattr(fname, name) < 0) {
1037 rsyserr(FERROR_XFER, errno,
1038 "rsync_xal_set: lremovexattr(%s,\"%s\") failed",
1039 full_fname(fname), name);
1040 ret = -1;
1041 } else /* make sure caller sets mtime */
1042 sxp->st.st_mtime = (time_t)-1;
1043 }
1044 }
1045
1046 return ret;
1047 }
1048
1049 /* Set extended attributes on indicated filename. */
1050 int set_xattr(const char *fname, const struct file_struct *file,
1051 const char *fnamecmp, stat_x *sxp)
1052 {
1053 rsync_xa_list *glst = rsync_xal_l.items;
1054 item_list *lst;
1055 int ndx;
1056
1057 if (dry_run)
1058 return 1; /* FIXME: --dry-run needs to compute this value */
1059
1060 if (read_only || list_only) {
1061 errno = EROFS;
1062 return -1;
1063 }
1064
1065 #ifdef NO_SPECIAL_XATTRS
1066 if (IS_SPECIAL(sxp->st.st_mode)) {
1067 errno = ENOTSUP;
1068 return -1;
1069 }
1070 #endif
1071 #ifdef NO_DEVICE_XATTRS
1072 if (IS_DEVICE(sxp->st.st_mode)) {
1073 errno = ENOTSUP;
1074 return -1;
1075 }
1076 #endif
1077 #ifdef NO_SYMLINK_XATTRS
1078 if (S_ISLNK(sxp->st.st_mode)) {
1079 errno = ENOTSUP;
1080 return -1;
1081 }
1082 #endif
1083
1084 ndx = F_XATTR(file);
1085 glst += ndx;
1086 lst = &glst->xa_items;
1087 return rsync_xal_set(fname, lst, fnamecmp, sxp);
1088 }
1089
1090 #ifdef SUPPORT_ACLS
1091 char *get_xattr_acl(const char *fname, int is_access_acl, size_t *len_p)
1092 {
1093 const char *name = is_access_acl ? XACC_ACL_ATTR : XDEF_ACL_ATTR;
1094 *len_p = 0; /* no extra data alloc needed from get_xattr_data() */
1095 return get_xattr_data(fname, name, len_p, 1);
1096 }
1097
1098 int set_xattr_acl(const char *fname, int is_access_acl, const char *buf, size_t buf_len)
1099 {
1100 const char *name = is_access_acl ? XACC_ACL_ATTR : XDEF_ACL_ATTR;
1101 if (sys_lsetxattr(fname, name, buf, buf_len) < 0) {
1102 rsyserr(FERROR_XFER, errno,
1103 "set_xattr_acl: lsetxattr(%s,\"%s\") failed",
1104 full_fname(fname), name);
1105 return -1;
1106 }
1107 return 0;
1108 }
1109
1110 int del_def_xattr_acl(const char *fname)
1111 {
1112 return sys_lremovexattr(fname, XDEF_ACL_ATTR);
1113 }
1114 #endif
1115
1116 int get_stat_xattr(const char *fname, int fd, STRUCT_STAT *fst, STRUCT_STAT *xst)
1117 {
1118 int mode, rdev_major, rdev_minor, uid, gid, len;
1119 char buf[256];
1120
1121 if (am_root >= 0 || IS_DEVICE(fst->st_mode) || IS_SPECIAL(fst->st_mode))
1122 return -1;
1123
1124 if (xst)
1125 *xst = *fst;
1126 else
1127 xst = fst;
1128 if (fname) {
1129 fd = -1;
1130 len = sys_lgetxattr(fname, XSTAT_ATTR, buf, sizeof buf - 1);
1131 } else {
1132 fname = "fd";
1133 len = sys_fgetxattr(fd, XSTAT_ATTR, buf, sizeof buf - 1);
1134 }
1135 if (len >= (int)sizeof buf) {
1136 len = -1;
1137 errno = ERANGE;
1138 }
1139 if (len < 0) {
1140 if (errno == ENOTSUP || errno == ENOATTR)
1141 return -1;
1142 if (errno == EPERM && S_ISLNK(fst->st_mode)) {
1143 xst->st_uid = 0;
1144 xst->st_gid = 0;
1145 return 0;
1146 }
1147 rsyserr(FERROR_XFER, errno, "failed to read xattr %s for %s",
1148 XSTAT_ATTR, full_fname(fname));
1149 return -1;
1150 }
1151 buf[len] = '\0';
1152
1153 if (sscanf(buf, "%o %d,%d %d:%d",
1154 &mode, &rdev_major, &rdev_minor, &uid, &gid) != 5) {
1155 rprintf(FERROR, "Corrupt %s xattr attached to %s: \"%s\"\n",
1156 XSTAT_ATTR, full_fname(fname), buf);
1157 exit_cleanup(RERR_FILEIO);
1158 }
1159
1160 xst->st_mode = from_wire_mode(mode);
1161 xst->st_rdev = MAKEDEV(rdev_major, rdev_minor);
1162 xst->st_uid = uid;
1163 xst->st_gid = gid;
1164
1165 return 0;
1166 }
1167
1168 int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
1169 {
1170 STRUCT_STAT fst, xst;
1171 dev_t rdev;
1172 mode_t mode, fmode;
1173
1174 if (dry_run)
1175 return 0;
1176
1177 if (read_only || list_only) {
1178 rsyserr(FERROR_XFER, EROFS, "failed to write xattr %s for %s",
1179 XSTAT_ATTR, full_fname(fname));
1180 return -1;
1181 }
1182
1183 if (x_lstat(fname, &fst, &xst) < 0) {
1184 rsyserr(FERROR_XFER, errno, "failed to re-stat %s",
1185 full_fname(fname));
1186 return -1;
1187 }
1188
1189 fst.st_mode &= (_S_IFMT | CHMOD_BITS);
1190 fmode = new_mode & (_S_IFMT | CHMOD_BITS);
1191
1192 if (IS_DEVICE(fmode)) {
1193 uint32 *devp = F_RDEV_P(file);
1194 rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
1195 } else
1196 rdev = 0;
1197
1198 /* Dump the special permissions and enable full owner access. */
1199 mode = (fst.st_mode & _S_IFMT) | (fmode & ACCESSPERMS)
1200 | (S_ISDIR(fst.st_mode) ? 0700 : 0600);
1201 if (fst.st_mode != mode)
1202 do_chmod(fname, mode);
1203 if (!IS_DEVICE(fst.st_mode))
1204 fst.st_rdev = 0; /* just in case */
1205
1206 if (mode == fmode && fst.st_rdev == rdev
1207 && fst.st_uid == F_OWNER(file) && fst.st_gid == F_GROUP(file)) {
1208 /* xst.st_mode will be 0 if there's no current stat xattr */
1209 if (xst.st_mode && sys_lremovexattr(fname, XSTAT_ATTR) < 0) {
1210 rsyserr(FERROR_XFER, errno,
1211 "delete of stat xattr failed for %s",
1212 full_fname(fname));
1213 return -1;
1214 }
1215 return 0;
1216 }
1217
1218 if (xst.st_mode != fmode || xst.st_rdev != rdev
1219 || xst.st_uid != F_OWNER(file) || xst.st_gid != F_GROUP(file)) {
1220 char buf[256];
1221 int len = snprintf(buf, sizeof buf, "%o %u,%u %u:%u",
1222 to_wire_mode(fmode),
1223 (int)major(rdev), (int)minor(rdev),
1224 F_OWNER(file), F_GROUP(file));
1225 if (sys_lsetxattr(fname, XSTAT_ATTR, buf, len) < 0) {
1226 if (errno == EPERM && S_ISLNK(fst.st_mode))
1227 return 0;
1228 rsyserr(FERROR_XFER, errno,
1229 "failed to write xattr %s for %s",
1230 XSTAT_ATTR, full_fname(fname));
1231 return -1;
1232 }
1233 }
1234
1235 return 0;
1236 }
1237
1238 int x_stat(const char *fname, STRUCT_STAT *fst, STRUCT_STAT *xst)
1239 {
1240 int ret = do_stat(fname, fst);
1241 if ((ret < 0 || get_stat_xattr(fname, -1, fst, xst) < 0) && xst)
1242 xst->st_mode = 0;
1243 return ret;
1244 }
1245
1246 int x_lstat(const char *fname, STRUCT_STAT *fst, STRUCT_STAT *xst)
1247 {
1248 int ret = do_lstat(fname, fst);
1249 if ((ret < 0 || get_stat_xattr(fname, -1, fst, xst) < 0) && xst)
1250 xst->st_mode = 0;
1251 return ret;
1252 }
1253
1254 int x_fstat(int fd, STRUCT_STAT *fst, STRUCT_STAT *xst)
1255 {
1256 int ret = do_fstat(fd, fst);
1257 if ((ret < 0 || get_stat_xattr(NULL, fd, fst, xst) < 0) && xst)
1258 xst->st_mode = 0;
1259 return ret;
1260 }
1261
1262 #endif /* SUPPORT_XATTRS */