pxar, acl: cleanup acl helper usage
use NixPath for Acl::set_file to avoid memduping the c string Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
5d85847f91
commit
4482f3fe11
|
@ -10,12 +10,12 @@ use nix::sys::stat::Mode;
|
||||||
|
|
||||||
use pxar::Metadata;
|
use pxar::Metadata;
|
||||||
|
|
||||||
|
use proxmox::c_result;
|
||||||
use proxmox::sys::error::SysError;
|
use proxmox::sys::error::SysError;
|
||||||
use proxmox::tools::fd::RawFdNum;
|
use proxmox::tools::fd::RawFdNum;
|
||||||
use proxmox::{c_result, c_try};
|
|
||||||
|
|
||||||
use crate::pxar::Flags;
|
|
||||||
use crate::pxar::tools::perms_from_metadata;
|
use crate::pxar::tools::perms_from_metadata;
|
||||||
|
use crate::pxar::Flags;
|
||||||
use crate::tools::{acl, fs, xattr};
|
use crate::tools::{acl, fs, xattr};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -97,7 +97,6 @@ pub fn apply_with_path<T: AsRef<Path>>(
|
||||||
|
|
||||||
pub fn apply(flags: Flags, metadata: &Metadata, fd: RawFd, file_name: &CStr) -> Result<(), Error> {
|
pub fn apply(flags: Flags, metadata: &Metadata, fd: RawFd, file_name: &CStr) -> 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();
|
||||||
let c_proc_path = c_proc_path.as_ptr();
|
|
||||||
|
|
||||||
if metadata.stat.flags != 0 {
|
if metadata.stat.flags != 0 {
|
||||||
todo!("apply flags!");
|
todo!("apply flags!");
|
||||||
|
@ -106,7 +105,7 @@ pub fn apply(flags: Flags, metadata: &Metadata, fd: RawFd, file_name: &CStr) ->
|
||||||
unsafe {
|
unsafe {
|
||||||
// UID and GID first, as this fails if we lose access anyway.
|
// UID and GID first, as this fails if we lose access anyway.
|
||||||
c_result!(libc::chown(
|
c_result!(libc::chown(
|
||||||
c_proc_path,
|
c_proc_path.as_ptr(),
|
||||||
metadata.stat.uid,
|
metadata.stat.uid,
|
||||||
metadata.stat.gid
|
metadata.stat.gid
|
||||||
))
|
))
|
||||||
|
@ -115,23 +114,25 @@ pub fn apply(flags: Flags, metadata: &Metadata, fd: RawFd, file_name: &CStr) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut skip_xattrs = false;
|
let mut skip_xattrs = false;
|
||||||
apply_xattrs(flags, c_proc_path, metadata, &mut skip_xattrs)?;
|
apply_xattrs(flags, c_proc_path.as_ptr(), metadata, &mut skip_xattrs)?;
|
||||||
add_fcaps(flags, c_proc_path, metadata, &mut skip_xattrs)?;
|
add_fcaps(flags, c_proc_path.as_ptr(), metadata, &mut skip_xattrs)?;
|
||||||
apply_acls(flags, c_proc_path, metadata)?;
|
apply_acls(flags, &c_proc_path, metadata)?;
|
||||||
apply_quota_project_id(flags, fd, metadata)?;
|
apply_quota_project_id(flags, fd, metadata)?;
|
||||||
|
|
||||||
// Finally mode and time. We may lose access with mode, but the changing the mode also
|
// Finally mode and time. We may lose access with mode, but the changing the mode also
|
||||||
// affects times.
|
// affects times.
|
||||||
if !metadata.is_symlink() {
|
if !metadata.is_symlink() {
|
||||||
c_result!(unsafe { libc::chmod(c_proc_path, perms_from_metadata(metadata)?.bits()) })
|
c_result!(unsafe {
|
||||||
.map(drop)
|
libc::chmod(c_proc_path.as_ptr(), perms_from_metadata(metadata)?.bits())
|
||||||
.or_else(allow_notsupp)?;
|
})
|
||||||
|
.map(drop)
|
||||||
|
.or_else(allow_notsupp)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = c_result!(unsafe {
|
let res = c_result!(unsafe {
|
||||||
libc::utimensat(
|
libc::utimensat(
|
||||||
libc::AT_FDCWD,
|
libc::AT_FDCWD,
|
||||||
c_proc_path,
|
c_proc_path.as_ptr(),
|
||||||
nsec_to_update_timespec(metadata.stat.mtime).as_ptr(),
|
nsec_to_update_timespec(metadata.stat.mtime).as_ptr(),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
|
@ -216,11 +217,7 @@ fn apply_xattrs(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_acls(
|
fn apply_acls(flags: Flags, c_proc_path: &CStr, metadata: &Metadata) -> Result<(), Error> {
|
||||||
flags: Flags,
|
|
||||||
c_proc_path: *const libc::c_char,
|
|
||||||
metadata: &Metadata,
|
|
||||||
) -> 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(());
|
||||||
}
|
}
|
||||||
|
@ -270,7 +267,7 @@ fn apply_acls(
|
||||||
bail!("Error while restoring ACL - ACL invalid");
|
bail!("Error while restoring ACL - ACL invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
c_try!(unsafe { acl::acl_set_file(c_proc_path, acl::ACL_TYPE_ACCESS, acl.ptr,) });
|
acl.set_file(c_proc_path, acl::ACL_TYPE_ACCESS)?;
|
||||||
drop(acl);
|
drop(acl);
|
||||||
|
|
||||||
// acl type default:
|
// acl type default:
|
||||||
|
@ -299,7 +296,7 @@ fn apply_acls(
|
||||||
bail!("Error while restoring ACL - ACL invalid");
|
bail!("Error while restoring ACL - ACL invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
c_try!(unsafe { acl::acl_set_file(c_proc_path, acl::ACL_TYPE_DEFAULT, acl.ptr,) });
|
acl.set_file(c_proc_path, acl::ACL_TYPE_DEFAULT)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -12,6 +12,7 @@ use std::ptr;
|
||||||
|
|
||||||
use libc::{c_char, c_int, c_uint, c_void};
|
use libc::{c_char, c_int, c_uint, c_void};
|
||||||
use nix::errno::Errno;
|
use nix::errno::Errno;
|
||||||
|
use nix::NixPath;
|
||||||
|
|
||||||
// from: acl/include/acl.h
|
// from: acl/include/acl.h
|
||||||
pub const ACL_UNDEFINED_ID: u32 = 0xffffffff;
|
pub const ACL_UNDEFINED_ID: u32 = 0xffffffff;
|
||||||
|
@ -49,8 +50,7 @@ pub const ACL_EA_VERSION: u32 = 0x0002;
|
||||||
#[link(name = "acl")]
|
#[link(name = "acl")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn acl_get_file(path: *const c_char, acl_type: ACLType) -> *mut c_void;
|
fn acl_get_file(path: *const c_char, acl_type: ACLType) -> *mut c_void;
|
||||||
// FIXME: remove 'pub' after the cleanup
|
fn acl_set_file(path: *const c_char, acl_type: ACLType, acl: *mut c_void) -> c_int;
|
||||||
pub(crate) fn acl_set_file(path: *const c_char, acl_type: ACLType, acl: *mut c_void) -> c_int;
|
|
||||||
fn acl_get_fd(fd: RawFd) -> *mut c_void;
|
fn acl_get_fd(fd: RawFd) -> *mut c_void;
|
||||||
fn acl_get_entry(acl: *const c_void, entry_id: c_int, entry: *mut *mut c_void) -> c_int;
|
fn acl_get_entry(acl: *const c_void, entry_id: c_int, entry: *mut *mut c_void) -> c_int;
|
||||||
fn acl_create_entry(acl: *mut *mut c_void, entry: *mut *mut c_void) -> c_int;
|
fn acl_create_entry(acl: *mut *mut c_void, entry: *mut *mut c_void) -> c_int;
|
||||||
|
@ -69,8 +69,7 @@ extern "C" {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ACL {
|
pub struct ACL {
|
||||||
// FIXME: remove 'pub' after the cleanup
|
ptr: *mut c_void,
|
||||||
pub(crate) ptr: *mut c_void,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ACL {
|
impl Drop for ACL {
|
||||||
|
@ -102,14 +101,11 @@ impl ACL {
|
||||||
Ok(ACL { ptr })
|
Ok(ACL { ptr })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_file<P: AsRef<Path>>(&self, path: P, acl_type: ACLType) -> Result<(), nix::errno::Errno> {
|
pub fn set_file<P: NixPath + ?Sized>(&self, path: &P, acl_type: ACLType) -> nix::Result<()> {
|
||||||
let path_cstr = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
|
path.with_nix_path(|path| {
|
||||||
let res = unsafe { acl_set_file(path_cstr.as_ptr(), acl_type, self.ptr) };
|
Errno::result(unsafe { acl_set_file(path.as_ptr(), acl_type, self.ptr) })
|
||||||
if res < 0 {
|
})?
|
||||||
return Err(Errno::last());
|
.map(drop)
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fd(fd: RawFd) -> Result<ACL, nix::errno::Errno> {
|
pub fn get_fd(fd: RawFd) -> Result<ACL, nix::errno::Errno> {
|
||||||
|
|
Loading…
Reference in New Issue