pxar: handle missing GROUP_OBJ ACL entries
Previously we did not store GROUP_OBJ ACL entries for directories, this means that these were lost which may potentially elevate group permissions if they were masked before via ACLs, so we also show a warning. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
9f40e09d0a
commit
79e58a903e
@ -1,6 +1,6 @@
|
|||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::OsString;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
use nix::dir::Dir;
|
use nix::dir::Dir;
|
||||||
@ -78,10 +78,6 @@ impl PxarDir {
|
|||||||
pub fn metadata(&self) -> &Metadata {
|
pub fn metadata(&self) -> &Metadata {
|
||||||
&self.metadata
|
&self.metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_name(&self) -> &OsStr {
|
|
||||||
&self.file_name
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PxarDirStack {
|
pub struct PxarDirStack {
|
||||||
@ -159,4 +155,8 @@ impl PxarDirStack {
|
|||||||
.try_as_borrowed_fd()
|
.try_as_borrowed_fd()
|
||||||
.ok_or_else(|| format_err!("lost track of directory file descriptors"))
|
.ok_or_else(|| format_err!("lost track of directory file descriptors"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &Path {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,6 +285,8 @@ impl Extractor {
|
|||||||
|
|
||||||
/// When done with a directory we can apply its metadata if it has been created.
|
/// When done with a directory we can apply its metadata if it has been created.
|
||||||
pub fn leave_directory(&mut self) -> Result<(), Error> {
|
pub fn leave_directory(&mut self) -> Result<(), Error> {
|
||||||
|
let path_info = self.dir_stack.path().to_owned();
|
||||||
|
|
||||||
let dir = self
|
let dir = self
|
||||||
.dir_stack
|
.dir_stack
|
||||||
.pop()
|
.pop()
|
||||||
@ -296,7 +298,7 @@ impl Extractor {
|
|||||||
self.feature_flags,
|
self.feature_flags,
|
||||||
dir.metadata(),
|
dir.metadata(),
|
||||||
fd.as_raw_fd(),
|
fd.as_raw_fd(),
|
||||||
&CString::new(dir.file_name().as_bytes())?,
|
&path_info,
|
||||||
&mut self.on_error,
|
&mut self.on_error,
|
||||||
)
|
)
|
||||||
.map_err(|err| format_err!("failed to apply directory metadata: {}", err))?;
|
.map_err(|err| format_err!("failed to apply directory metadata: {}", err))?;
|
||||||
@ -329,6 +331,7 @@ impl Extractor {
|
|||||||
metadata,
|
metadata,
|
||||||
parent,
|
parent,
|
||||||
file_name,
|
file_name,
|
||||||
|
self.dir_stack.path(),
|
||||||
&mut self.on_error,
|
&mut self.on_error,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -382,6 +385,7 @@ impl Extractor {
|
|||||||
metadata,
|
metadata,
|
||||||
parent,
|
parent,
|
||||||
file_name,
|
file_name,
|
||||||
|
self.dir_stack.path(),
|
||||||
&mut self.on_error,
|
&mut self.on_error,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -437,7 +441,7 @@ impl Extractor {
|
|||||||
self.feature_flags,
|
self.feature_flags,
|
||||||
metadata,
|
metadata,
|
||||||
file.as_raw_fd(),
|
file.as_raw_fd(),
|
||||||
file_name,
|
self.dir_stack.path(),
|
||||||
&mut self.on_error,
|
&mut self.on_error,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -494,7 +498,7 @@ impl Extractor {
|
|||||||
self.feature_flags,
|
self.feature_flags,
|
||||||
metadata,
|
metadata,
|
||||||
file.as_raw_fd(),
|
file.as_raw_fd(),
|
||||||
file_name,
|
self.dir_stack.path(),
|
||||||
&mut self.on_error,
|
&mut self.on_error,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
use nix::errno::Errno;
|
use nix::errno::Errno;
|
||||||
@ -62,6 +63,7 @@ pub fn apply_at(
|
|||||||
metadata: &Metadata,
|
metadata: &Metadata,
|
||||||
parent: RawFd,
|
parent: RawFd,
|
||||||
file_name: &CStr,
|
file_name: &CStr,
|
||||||
|
path_info: &Path,
|
||||||
on_error: &mut (dyn FnMut(Error) -> Result<(), Error> + Send),
|
on_error: &mut (dyn FnMut(Error) -> Result<(), Error> + Send),
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let fd = proxmox::tools::fd::Fd::openat(
|
let fd = proxmox::tools::fd::Fd::openat(
|
||||||
@ -71,7 +73,7 @@ pub fn apply_at(
|
|||||||
Mode::empty(),
|
Mode::empty(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
apply(flags, metadata, fd.as_raw_fd(), file_name, on_error)
|
apply(flags, metadata, fd.as_raw_fd(), path_info, on_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_initial_flags(
|
pub fn apply_initial_flags(
|
||||||
@ -94,7 +96,7 @@ pub fn apply(
|
|||||||
flags: Flags,
|
flags: Flags,
|
||||||
metadata: &Metadata,
|
metadata: &Metadata,
|
||||||
fd: RawFd,
|
fd: RawFd,
|
||||||
file_name: &CStr,
|
path_info: &Path,
|
||||||
on_error: &mut (dyn FnMut(Error) -> Result<(), Error> + Send),
|
on_error: &mut (dyn FnMut(Error) -> Result<(), Error> + Send),
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let c_proc_path = CString::new(format!("/proc/self/fd/{}", fd)).unwrap();
|
let c_proc_path = CString::new(format!("/proc/self/fd/{}", fd)).unwrap();
|
||||||
@ -116,7 +118,7 @@ pub fn apply(
|
|||||||
apply_xattrs(flags, c_proc_path.as_ptr(), metadata, &mut skip_xattrs)
|
apply_xattrs(flags, c_proc_path.as_ptr(), metadata, &mut skip_xattrs)
|
||||||
.or_else(&mut *on_error)?;
|
.or_else(&mut *on_error)?;
|
||||||
add_fcaps(flags, c_proc_path.as_ptr(), metadata, &mut skip_xattrs).or_else(&mut *on_error)?;
|
add_fcaps(flags, c_proc_path.as_ptr(), metadata, &mut skip_xattrs).or_else(&mut *on_error)?;
|
||||||
apply_acls(flags, &c_proc_path, metadata)
|
apply_acls(flags, &c_proc_path, metadata, path_info)
|
||||||
.map_err(|err| format_err!("failed to apply acls: {}", err))
|
.map_err(|err| format_err!("failed to apply acls: {}", err))
|
||||||
.or_else(&mut *on_error)?;
|
.or_else(&mut *on_error)?;
|
||||||
apply_quota_project_id(flags, fd, metadata).or_else(&mut *on_error)?;
|
apply_quota_project_id(flags, fd, metadata).or_else(&mut *on_error)?;
|
||||||
@ -147,7 +149,7 @@ pub fn apply(
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
on_error(format_err!(
|
on_error(format_err!(
|
||||||
"failed to restore mtime attribute on {:?}: {}",
|
"failed to restore mtime attribute on {:?}: {}",
|
||||||
file_name,
|
path_info,
|
||||||
err
|
err
|
||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
@ -227,7 +229,12 @@ fn apply_xattrs(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_acls(flags: Flags, c_proc_path: &CStr, metadata: &Metadata) -> Result<(), Error> {
|
fn apply_acls(
|
||||||
|
flags: Flags,
|
||||||
|
c_proc_path: &CStr,
|
||||||
|
metadata: &Metadata,
|
||||||
|
path_info: &Path,
|
||||||
|
) -> Result<(), Error> {
|
||||||
if !flags.contains(Flags::WITH_ACL) || metadata.acl.is_empty() {
|
if !flags.contains(Flags::WITH_ACL) || metadata.acl.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -257,11 +264,17 @@ fn apply_acls(flags: Flags, c_proc_path: &CStr, metadata: &Metadata) -> Result<(
|
|||||||
acl.add_entry_full(acl::ACL_GROUP_OBJ, None, group_obj.permissions.0)?;
|
acl.add_entry_full(acl::ACL_GROUP_OBJ, None, group_obj.permissions.0)?;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
acl.add_entry_full(
|
let mode = acl::mode_group_to_acl_permissions(metadata.stat.mode);
|
||||||
acl::ACL_GROUP_OBJ,
|
|
||||||
None,
|
acl.add_entry_full(acl::ACL_GROUP_OBJ, None, mode)?;
|
||||||
acl::mode_group_to_acl_permissions(metadata.stat.mode),
|
|
||||||
)?;
|
if !metadata.acl.users.is_empty() || !metadata.acl.groups.is_empty() {
|
||||||
|
eprintln!(
|
||||||
|
"Warning: {:?}: Missing GROUP_OBJ entry in ACL, resetting to value of MASK",
|
||||||
|
path_info,
|
||||||
|
);
|
||||||
|
acl.add_entry_full(acl::ACL_MASK, None, mode)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user