From 0502ce6da3d3d8633f9f81dc8b030322d66235ab Mon Sep 17 00:00:00 2001 From: Christian Ebner Date: Tue, 28 Jan 2020 12:42:22 +0100 Subject: [PATCH] tools::acl: Add helpers to create extended attribute buffer. This helpers are used to construct the extended attributes values from the ACLs stored in the pxar archive. Signed-off-by: Christian Ebner Signed-off-by: Wolfgang Bumiller --- src/tools/acl.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/tools/acl.rs b/src/tools/acl.rs index 596c4348..de5c1c82 100644 --- a/src/tools/acl.rs +++ b/src/tools/acl.rs @@ -13,6 +13,8 @@ use std::ptr; use libc::{c_char, c_int, c_uint, c_void}; use nix::errno::Errno; +// from: acl/include/acl.h +pub const ACL_UNDEFINED_ID: u32 = 0xffffffff; // acl_perm_t values pub type ACLPerm = c_uint; pub const ACL_READ: ACLPerm = 0x04; @@ -38,6 +40,12 @@ pub const ACL_TYPE_DEFAULT: ACLType = 0x4000; pub const ACL_FIRST_ENTRY: c_int = 0; pub const ACL_NEXT_ENTRY: c_int = 1; +// acl to extended attribute names constants +// from: acl/include/acl_ea.h +pub const ACL_EA_ACCESS: &'static str = "system.posix_acl_access"; +pub const ACL_EA_DEFAULT: &'static str = "system.posix_acl_default"; +pub const ACL_EA_VERSION: u32 = 0x0002; + #[link(name = "acl")] extern "C" { fn acl_get_file(path: *const c_char, acl_type: ACLType) -> *mut c_void; @@ -285,3 +293,39 @@ pub fn mode_group_to_acl_permissions(mode: u64) -> u64 { pub fn mode_other_to_acl_permissions(mode: u64) -> u64 { mode & 7 } + +/// Buffer to compose ACLs as extended attribute. +pub struct ACLXAttrBuffer { + buffer: Vec, +} + +impl ACLXAttrBuffer { + /// Create a new buffer to write ACLs as extended attribute. + /// + /// `version` defines the ACL_EA_VERSION found in acl/include/acl_ea.h + pub fn new(version: u32) -> Self { + let mut buffer = Vec::new(); + buffer.extend_from_slice(&version.to_le_bytes()); + Self { buffer } + } + + /// Add ACL entry to buffer. + pub fn add_entry(&mut self, tag: ACLTag, qualifier: Option, permissions: u64) { + self.buffer.extend_from_slice(&(tag as u16).to_le_bytes()); + self.buffer.extend_from_slice(&(permissions as u16).to_le_bytes()); + match qualifier { + Some(qualifier) => self.buffer.extend_from_slice(&(qualifier as u32).to_le_bytes()), + None => self.buffer.extend_from_slice(&ACL_UNDEFINED_ID.to_le_bytes()), + } + } + + /// Length of the buffer in bytes. + pub fn len(&self) -> usize { + self.buffer.len() + } + + /// Borrow raw buffer as mut slice. + pub fn as_mut_slice(&mut self) -> &mut [u8] { + self.buffer.as_mut_slice() + } +}