acl: add trivial ACL printing
This commit is contained in:
parent
d9f9ca9a43
commit
fd3f1bfc34
@ -10,6 +10,16 @@ include (nc)
|
||||
include_directories(.)
|
||||
|
||||
|
||||
###############################################################################
|
||||
add_library(emory
|
||||
acl.cpp
|
||||
acl.hpp
|
||||
)
|
||||
|
||||
|
||||
target_link_libraries(emory cruft acl)
|
||||
|
||||
|
||||
###############################################################################
|
||||
option (TESTS "enable unit testing" ON)
|
||||
if (TESTS)
|
||||
@ -25,5 +35,5 @@ add_subdirectory(cruft/crypto)
|
||||
###############################################################################
|
||||
foreach (t analyse compare stat)
|
||||
add_executable ("${t}" "tools/${t}.cpp")
|
||||
target_link_libraries("${t}" cruft-crypto cruft-util)
|
||||
target_link_libraries("${t}" emory cruft-crypto cruft)
|
||||
endforeach()
|
||||
|
227
acl.cpp
Normal file
227
acl.cpp
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2019, Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "acl.hpp"
|
||||
|
||||
#include <acl/libacl.h>
|
||||
|
||||
#include <cruft/util/posix/except.hpp>
|
||||
#include <cruft/util/scoped.hpp>
|
||||
#include <cruft/util/iterator/infix.hpp>
|
||||
|
||||
|
||||
using cruft::acl;
|
||||
using cruft::entry;
|
||||
using cruft::permset;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
acl::acl (int count)
|
||||
: acl (acl_init (count))
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
acl::acl (std::filesystem::path const &path, acl_type_t type)
|
||||
: acl (acl_get_file (path.u8string ().c_str (), type))
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
acl::acl (acl_t &&_native)
|
||||
: m_native (_native)
|
||||
{
|
||||
if (!m_native)
|
||||
cruft::posix::error::throw_code ();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
acl::~acl ()
|
||||
{
|
||||
if (m_native)
|
||||
acl_free (m_native);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
acl acl::dup (void) const
|
||||
{
|
||||
return acl {
|
||||
acl_dup (m_native)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
acl::iterator::iterator (acl const &_parent)
|
||||
: m_parent (&_parent)
|
||||
{
|
||||
fetch (ACL_FIRST_ENTRY);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
acl::iterator::iterator ()
|
||||
: m_parent (nullptr)
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
acl::iterator::value_type
|
||||
acl::iterator::operator* (void)
|
||||
{
|
||||
return entry { m_value };
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
acl::iterator&
|
||||
acl::iterator::operator++ ()
|
||||
{
|
||||
fetch (ACL_NEXT_ENTRY);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool
|
||||
acl::iterator::operator== (iterator const &rhs) const
|
||||
{
|
||||
return m_parent == rhs.m_parent;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool
|
||||
acl::iterator::operator!= (iterator const &rhs) const
|
||||
{
|
||||
return m_parent != rhs.m_parent;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
acl::iterator::fetch (int pos)
|
||||
{
|
||||
auto const res = acl_get_entry (m_parent->native (), pos, &m_value);
|
||||
|
||||
switch (res) {
|
||||
case 0: m_parent = nullptr; return;
|
||||
case 1: return;
|
||||
default:
|
||||
cruft::posix::error::throw_code ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
acl::const_iterator
|
||||
acl::begin (void) const
|
||||
{
|
||||
return const_iterator { *this };
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
acl::const_iterator
|
||||
acl::end (void) const
|
||||
{
|
||||
return iterator {};
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int acl::size (void) const
|
||||
{
|
||||
return cruft::posix::error::try_call (acl_entries, m_native);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
entry::entry (acl_entry_t _native)
|
||||
: m_native (_native)
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
acl_tag_t
|
||||
entry::tag (void) const
|
||||
{
|
||||
acl_tag_t res;
|
||||
cruft::posix::error::try_call (acl_get_tag_type, m_native, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class cruft::permset
|
||||
entry::permset (void) const
|
||||
{
|
||||
acl_permset_t res;
|
||||
cruft::posix::error::try_call (acl_get_permset, m_native, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
permset::permset (acl_permset_t _native)
|
||||
: m_native (_native)
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool permset::operator& (acl_perm_t val) const
|
||||
{
|
||||
return cruft::posix::error::try_call (acl_get_perm, m_native, val);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
std::ostream&
|
||||
cruft::operator<< (std::ostream &os, cruft::acl const &val)
|
||||
{
|
||||
return os << "[ " << cruft::iterator::make_infix (val) << " ]";
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
std::ostream&
|
||||
cruft::operator<< (std::ostream &os, cruft::entry const &val)
|
||||
{
|
||||
os << "{ ";
|
||||
|
||||
auto t = val.tag ();
|
||||
|
||||
switch (t) {
|
||||
case ACL_USER: os << "uid: " << +val.qualifier<uid_t> (); break;
|
||||
case ACL_GROUP: os << "gid: " << +val.qualifier<gid_t> (); break;
|
||||
|
||||
case ACL_USER_OBJ: os << "owner: null"; break;
|
||||
case ACL_GROUP_OBJ: os << "group: null"; break;
|
||||
case ACL_MASK: os << "mask: null"; break;
|
||||
case ACL_OTHER: os << "other: null"; break;
|
||||
default:
|
||||
unhandled (t);
|
||||
}
|
||||
|
||||
os << ", permset: " << val.permset () << " }";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
std::ostream&
|
||||
cruft::operator<< (std::ostream &os, cruft::permset const &val)
|
||||
{
|
||||
return os << ((val & ACL_READ ) ? 'r' : '_')
|
||||
<< ((val & ACL_WRITE ) ? 'w' : '_')
|
||||
<< ((val & ACL_EXECUTE) ? 'x' : '_');
|
||||
}
|
139
acl.hpp
Normal file
139
acl.hpp
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2019, Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cruft/util/std.hpp>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <filesystem>
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
|
||||
#include <sys/acl.h>
|
||||
|
||||
|
||||
namespace cruft {
|
||||
/// A combination of read, write, and/or execute flags.
|
||||
class permset {
|
||||
public:
|
||||
permset (acl_permset_t _native);
|
||||
|
||||
bool operator& (acl_perm_t) const;
|
||||
|
||||
private:
|
||||
acl_permset_t m_native;
|
||||
};
|
||||
|
||||
|
||||
/// One single entry in an ACL. Contains a tag, qualifier, and permset.
|
||||
class entry {
|
||||
public:
|
||||
explicit entry (acl_entry_t);
|
||||
|
||||
acl_tag_t tag (void) const;
|
||||
|
||||
// It would be nice to use a tagged union, but uid_t and gid_t would
|
||||
// clash if we used something like std::variant. And we can't just
|
||||
// return an int because some systems have larger objects (eg, MacOS
|
||||
// with ACL_EXTENDED_ALLOW returns a guid_t).
|
||||
template <typename ValueT>
|
||||
ValueT qualifier (void) const
|
||||
{
|
||||
static_assert (std::is_pod_v<ValueT>);
|
||||
|
||||
auto data = acl_get_qualifier (m_native);
|
||||
|
||||
union {
|
||||
u08 raw[sizeof (ValueT)];
|
||||
ValueT res;
|
||||
};
|
||||
|
||||
memcpy (raw, data, sizeof (ValueT));
|
||||
acl_free (data);
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
class permset permset (void) const;
|
||||
|
||||
acl_entry_t& native (void) &;
|
||||
acl_entry_t const& native (void) const&;
|
||||
|
||||
private:
|
||||
acl_entry_t m_native;
|
||||
};
|
||||
|
||||
|
||||
/// A context for a ACL operations.
|
||||
class acl {
|
||||
public:
|
||||
using value_type = entry;
|
||||
|
||||
explicit acl (int count);
|
||||
explicit acl (acl_t &&);
|
||||
acl (std::filesystem::path const&, acl_type_t);
|
||||
|
||||
acl (acl&&);
|
||||
acl& operator= (acl&&);
|
||||
|
||||
acl (acl const&) = delete;
|
||||
acl& operator= (acl const&) = delete;
|
||||
|
||||
~acl ();
|
||||
|
||||
acl dup (void) const;
|
||||
|
||||
class iterator {
|
||||
public:
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using difference_type = int;
|
||||
using value_type = entry;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
|
||||
explicit iterator ();
|
||||
explicit iterator (acl const &parent);
|
||||
|
||||
iterator& operator++ ();
|
||||
value_type operator* ();
|
||||
|
||||
bool operator== (iterator const&) const;
|
||||
bool operator!= (iterator const&) const;
|
||||
|
||||
private:
|
||||
void fetch (int pos);
|
||||
|
||||
acl const *m_parent;
|
||||
acl_entry_t m_value;
|
||||
};
|
||||
|
||||
using const_iterator = iterator;
|
||||
|
||||
//iterator begin (void);
|
||||
//iterator end (void);
|
||||
|
||||
const_iterator begin (void) const;
|
||||
const_iterator end (void) const;
|
||||
|
||||
const_iterator cbegin (void) const;
|
||||
const_iterator cend (void) const;
|
||||
|
||||
int size (void) const;
|
||||
|
||||
acl_t& native (void)& { return m_native; }
|
||||
acl_t const& native (void) const& { return m_native; }
|
||||
|
||||
private:
|
||||
acl_t m_native;
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream&, acl const&);
|
||||
std::ostream& operator<< (std::ostream&, entry const&);
|
||||
std::ostream& operator<< (std::ostream&, permset const&);
|
||||
}
|
@ -1,3 +1,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/acl.h>
|
||||
#include "../acl.hpp"
|
||||
|
||||
#include <cruft/util/bitwise.hpp>
|
||||
#include <cruft/util/posix/except.hpp>
|
||||
#include <cruft/util/string.hpp>
|
||||
@ -145,6 +150,13 @@ void do_xattr (char const *path)
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void do_acl (char const *path)
|
||||
{
|
||||
std::cout << cruft::acl (path, ACL_TYPE_ACCESS) << '\n';
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
@ -159,6 +171,7 @@ int main (int argc, char **argv)
|
||||
char const *path = argv[i];
|
||||
do_stat (path);
|
||||
do_xattr (path);
|
||||
do_acl (path);
|
||||
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user