| 470 | } |
| 471 | |
| 472 | static int get_rsync_acl(const char *fname, rsync_acl *racl, |
| 473 | SMB_ACL_TYPE_T type, mode_t mode) |
| 474 | { |
| 475 | SMB_ACL_T sacl; |
| 476 | |
| 477 | #ifdef SUPPORT_XATTRS |
| 478 | /* --fake-super support: load ACLs from an xattr. */ |
| 479 | if (am_root < 0) { |
| 480 | char *buf; |
| 481 | size_t len; |
| 482 | int cnt; |
| 483 | |
| 484 | if ((buf = get_xattr_acl(fname, type == SMB_ACL_TYPE_ACCESS, &len)) == NULL) |
| 485 | return 0; |
| 486 | cnt = (len - 4*4) / (4+4); |
| 487 | if (len < 4*4 || len != (size_t)cnt*(4+4) + 4*4) { |
| 488 | free(buf); |
| 489 | return -1; |
| 490 | } |
| 491 | |
| 492 | racl->user_obj = IVAL(buf, 0); |
| 493 | if (racl->user_obj == NO_ENTRY) |
| 494 | racl->user_obj = (mode >> 6) & 7; |
| 495 | racl->group_obj = IVAL(buf, 4); |
| 496 | if (racl->group_obj == NO_ENTRY) |
| 497 | racl->group_obj = (mode >> 3) & 7; |
| 498 | racl->mask_obj = IVAL(buf, 8); |
| 499 | racl->other_obj = IVAL(buf, 12); |
| 500 | if (racl->other_obj == NO_ENTRY) |
| 501 | racl->other_obj = mode & 7; |
| 502 | |
| 503 | if (cnt) { |
| 504 | char *bp = buf + 4*4; |
| 505 | id_access *ida = racl->names.idas = new_array(id_access, cnt); |
| 506 | racl->names.count = cnt; |
| 507 | for ( ; cnt--; ida++, bp += 4+4) { |
| 508 | ida->id = IVAL(bp, 0); |
| 509 | ida->access = IVAL(bp, 4); |
| 510 | } |
| 511 | } |
| 512 | free(buf); |
| 513 | return 0; |
| 514 | } |
| 515 | #endif |
| 516 | |
| 517 | if ((sacl = sys_acl_get_file(fname, type)) != 0) { |
| 518 | BOOL ok = unpack_smb_acl(sacl, racl); |
| 519 | |
| 520 | sys_acl_free_acl(sacl); |
| 521 | if (!ok) { |
| 522 | rsyserr(FERROR_XFER, errno, "get_acl: unpack_smb_acl(%s)", fname); |
| 523 | return -1; |
| 524 | } |
| 525 | } else if (no_acl_syscall_error(errno)) { |
| 526 | /* ACLs are not supported, so pretend we have a basic ACL. */ |
| 527 | if (type == SMB_ACL_TYPE_ACCESS) |
| 528 | rsync_acl_fake_perms(racl, mode); |
| 529 | } else { |
no test coverage detected