Skip to content

Commit

Permalink
Add link ownership rules. (#371)
Browse files Browse the repository at this point in the history
  • Loading branch information
stswidwinski authored Aug 15, 2024
1 parent cdf5b6f commit f952189
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
6 changes: 6 additions & 0 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,12 @@ impl<'a> EntryFields<'a> {
),
)
})?;
// While permissions on symlinks are meaningless on most systems, the ownership
// of symlinks is important as it dictates the access control to the symlink
// itself.
if self.preserve_ownerships {
set_ownerships(dst, &None, self.header.uid()?, self.header.gid()?)?;
}
if self.preserve_mtime {
if let Some(mtime) = get_mtime(&self.header) {
filetime::set_symlink_file_times(dst, mtime, mtime).map_err(|e| {
Expand Down
28 changes: 24 additions & 4 deletions tests/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,20 @@ fn ownership_preserving() {
t!(header.set_path("iamuid580800002"));
header.set_cksum();
t!(ar.append(&header, data));
// directory 1 with uid = 580800002, gid = 580800002
header.set_entry_type(EntryType::Directory);
header.set_gid(580800002);
header.set_uid(580800002);
t!(header.set_path("iamuid580800002dir"));
header.set_cksum();
t!(ar.append(&header, data));
// symlink to file 1
header.set_entry_type(EntryType::Symlink);
header.set_gid(580800002);
header.set_uid(580800002);
t!(header.set_path("iamuid580800000symlink"));
header.set_cksum();
t!(ar.append_link(&mut header, "iamuid580800000symlink", "iamuid580800000"));
t!(ar.finish());

let rdr = Cursor::new(t!(ar.into_inner()));
Expand All @@ -1467,18 +1481,24 @@ fn ownership_preserving() {
ar.set_preserve_ownerships(true);

if unsafe { libc::getuid() } == 0 {
assert!(ar.unpack(td.path()).is_ok());
ar.unpack(td.path()).unwrap();
// validate against premade files
// iamuid580800001 has this ownership: 580800001:580800000
let meta = std::fs::metadata(td.path().join("iamuid580800000")).unwrap();
let meta = std::fs::symlink_metadata(td.path().join("iamuid580800000")).unwrap();
assert_eq!(meta.uid(), 580800000);
assert_eq!(meta.gid(), 580800000);
let meta = std::fs::metadata(td.path().join("iamuid580800001")).unwrap();
let meta = std::fs::symlink_metadata(td.path().join("iamuid580800001")).unwrap();
assert_eq!(meta.uid(), 580800001);
assert_eq!(meta.gid(), 580800000);
let meta = std::fs::metadata(td.path().join("iamuid580800002")).unwrap();
let meta = std::fs::symlink_metadata(td.path().join("iamuid580800002")).unwrap();
assert_eq!(meta.uid(), 580800002);
assert_eq!(meta.gid(), 580800002);
let meta = std::fs::symlink_metadata(td.path().join("iamuid580800002dir")).unwrap();
assert_eq!(meta.uid(), 580800002);
assert_eq!(meta.gid(), 580800002);
let meta = std::fs::symlink_metadata(td.path().join("iamuid580800000symlink")).unwrap();
assert_eq!(meta.uid(), 580800002);
assert_eq!(meta.gid(), 580800002)
} else {
// it's not possible to unpack tar while preserving ownership
// without root permissions
Expand Down

0 comments on commit f952189

Please sign in to comment.