UnshiftACL unshifts the uid/gid in the raw ACL entry.
(value string, set *Set)
| 592 | |
| 593 | // UnshiftACL unshifts the uid/gid in the raw ACL entry. |
| 594 | func UnshiftACL(value string, set *Set) (string, error) { |
| 595 | if set == nil { |
| 596 | return "", errors.New("Invalid Set supplied") |
| 597 | } |
| 598 | |
| 599 | buf := []byte(value) |
| 600 | cBuf := C.CBytes(buf) |
| 601 | defer C.free(cBuf) |
| 602 | var header *C.struct_posix_acl_xattr_header = (*C.struct_posix_acl_xattr_header)(cBuf) |
| 603 | |
| 604 | size := len(buf) |
| 605 | if size < int(unsafe.Sizeof(*header)) { |
| 606 | return "", errors.New("Invalid ACL size") |
| 607 | } |
| 608 | |
| 609 | if header.a_version != C.native_to_le32(C.POSIX_ACL_XATTR_VERSION) { |
| 610 | return "", fmt.Errorf("Invalid ACL header version %d != %d", header.a_version, C.native_to_le32(C.POSIX_ACL_XATTR_VERSION)) |
| 611 | } |
| 612 | |
| 613 | count := C.posix_acl_xattr_count(C.size_t(size)) |
| 614 | if count < 0 { |
| 615 | return "", errors.New("Invalid ACL count") |
| 616 | } |
| 617 | |
| 618 | if count == 0 { |
| 619 | return "", errors.New("No valid ACLs found") |
| 620 | } |
| 621 | |
| 622 | entryPtr := C.posix_entry_start(unsafe.Pointer(header)) |
| 623 | endEntryPtr := C.posix_entry_end(entryPtr, C.size_t(count)) |
| 624 | for entryPtr != endEntryPtr { |
| 625 | entry := (*C.struct_posix_acl_xattr_entry)(entryPtr) |
| 626 | switch C.le16_to_native(entry.e_tag) { |
| 627 | case C.ACL_USER: |
| 628 | ouid := int64(C.le32_to_native(entry.e_id)) |
| 629 | uid, _ := set.ShiftFromNS(ouid, -1) |
| 630 | if int(uid) != -1 { |
| 631 | entry.e_id = C.native_to_le32(C.int(uid)) |
| 632 | logger.Debugf("Unshifting ACL_USER from uid %d to uid %d", ouid, uid) |
| 633 | } |
| 634 | |
| 635 | case C.ACL_GROUP: |
| 636 | ogid := int64(C.le32_to_native(entry.e_id)) |
| 637 | _, gid := set.ShiftFromNS(-1, ogid) |
| 638 | if int(gid) != -1 { |
| 639 | entry.e_id = C.native_to_le32(C.int(gid)) |
| 640 | logger.Debugf("Unshifting ACL_GROUP from gid %d to gid %d", ogid, gid) |
| 641 | } |
| 642 | |
| 643 | case C.ACL_USER_OBJ: |
| 644 | logger.Debugf("Ignoring ACL type ACL_USER_OBJ") |
| 645 | case C.ACL_GROUP_OBJ: |
| 646 | logger.Debugf("Ignoring ACL type ACL_GROUP_OBJ") |
| 647 | case C.ACL_MASK: |
| 648 | logger.Debugf("Ignoring ACL type ACL_MASK") |
| 649 | case C.ACL_OTHER: |
| 650 | logger.Debugf("Ignoring ACL type ACL_OTHER") |
| 651 | default: |
no test coverage detected
searching dependent graphs…