//------------------------------------------------------------------------------
//! @file Acl.hh
//------------------------------------------------------------------------------
/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2017 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#pragma once
#include "mgm/Namespace.hh"
#include "common/Mapping.hh"
#include "namespace/interface/IContainerMD.hh"
#include "namespace/interface/IFileMD.hh"
#include
#include
#define P_OK 8 /* Test for workflow permission. */
class XrdOucErrInfo;
EOSMGMNAMESPACE_BEGIN
//------------------------------------------------------------------------------
//! Class implementing access control list interpretation.
//! ACL rules used in the constructor or in the Set function are strings with
//! the following format:
//! rule= 'u:|g:|egroup::{arw[o]ximc(!u)
//! (+u)(!d)(+d)q}|z:xmc(!u)(+u)(!d)(+d)q}'
//------------------------------------------------------------------------------
class Acl
{
public: // [+] prevents '+' interpreted as "one or more"
static constexpr auto sRegexUsrGenericAcl =
"^(((((u|g|k):(([0-9]+)|([\\.[:alnum:]_-]+)))|(egroup:([\\.[:alnum:]_-]+))|(z)):"
"(!?(a|r|w|wo|x|i|m|[+]?d|[+]?u|q|c))+)[,]?)*$";
static constexpr auto sRegexSysGenericAcl =
"^(((((u|g|k):(([0-9]+)|([\\.[:alnum:]_-]+)))|(egroup:([\\.[:alnum:]_-]+))|(z)):"
"(!?(a|r|w|wo|x|i|m|!m|!d|[+]d|!u|[+]u|q|c|p))+)[,]?)*$";
static constexpr auto sRegexUsrNumericAcl =
"^(((((u|g):(([0-9]+)))|(egroup:([\\.[:alnum:]_-]+))|(z)):"
"(!?(a|r|w|wo|x|i|m|[+]?d|[+]?u|q|c))+)[,]?)*$";
static constexpr auto sRegexSysNumericAcl =
"^(((((u|g):(([0-9]+)))|(egroup:([\\.[:alnum:]_-]+))|(z)):"
"(!?(a|r|w|wo|x|i|m|!m|!d|[+]d|!u|[+]u|q|c|p))+)[,]?)*$";
//----------------------------------------------------------------------------
//! Use regex to check ACL format / syntax
//!
//! @param value value to check
//! @param error error datastructure
//! @param is_sys_acl boolean indicating a sys acl entry which might have a
//! p: rule
//! @param check_numeric if true use numeric format of the regex
//!
//! return boolean indicating validity
//----------------------------------------------------------------------------
static bool IsValid(const std::string& value, XrdOucErrInfo& error,
bool is_sys_acl = false, bool check_numeric = false);
//----------------------------------------------------------------------------
//! By default convert the uid/gid(s) to numeric representation. If to_string
//! is set to true then convert from numeric to string representation.
//!
//! @param acl_val acl string which is modified in-place
//! @param to_string by default false, if true convert uid/gids(s) from
//! numeric to string representation
//!
//! @return 0 if conversion successful
//----------------------------------------------------------------------------
static int ConvertIds(std::string& acl_val, bool to_string = false);
//----------------------------------------------------------------------------
//! Default Constructor
//----------------------------------------------------------------------------
Acl():
mCanRead(false), mCanNotRead(false), mCanWrite(false), mCanNotWrite(false),
mCanWriteOnce(false),
mCanUpdate(false), mCanNotUpdate(false), mCanBrowse(false),
mCanNotBrowse(false),
mCanChmod(false), mCanChown(false), mCanNotDelete(false),
mCanNotChmod(false), mCanDelete(false), mCanSetQuota(false), mHasAcl(false),
mHasEgroup(false), mIsMutable(false), mCanArchive(false), mCanPrepare(false)
{}
//----------------------------------------------------------------------------
//! Constructor
//!
//! @param sysacl system acl definition string
//! 'u:|g:|egroup::{rwxom(!d)(+d)(!u)(+u)}
//! |z:{rw[o]xmc(!u)(+u)(!d)(+d)q}'
//! @param useracl user acl definition string
//! 'u:|g:|egroup::{rwxom(!d)(+d)(!u)(+u)}
//! |z:{rw[o]xmc(!u)(+u)(!d)(+d)q}'
//! @param vid virtual id to match ACL
//! @param allowUserAcl if true evaluate also the user acl for the permissions
//----------------------------------------------------------------------------
Acl(std::string sysacl, std::string useracl,
const eos::common::VirtualIdentity& vid, bool allowUserAcl = false);
/*---------------------------------------------------------------------------*/
//! Constructor from XAttrMap
/*---------------------------------------------------------------------------*/
Acl(const eos::IContainerMD::XAttrMap& xattrmap,
const eos::common::VirtualIdentity& vid);
//----------------------------------------------------------------------------
//! Constructor by path
//!
//! @param parent path where to read the acl attributes from
//! @param error return error object
//! @param vid virtual id to match ACL
//! @param attr map returns all the attributes from path
//! @param lockNs should we lock the namespace when retrieveng the attribute map
//----------------------------------------------------------------------------
Acl(const char* path, XrdOucErrInfo& error,
const eos::common::VirtualIdentity& vid,
eos::IContainerMD::XAttrMap& attrmap, bool lockNs);
//----------------------------------------------------------------------------
//! Destructor
//----------------------------------------------------------------------------
virtual ~Acl() = default;
//----------------------------------------------------------------------------
// Set Acls by interpreting the attribute map
//----------------------------------------------------------------------------
void SetFromAttrMap(const eos::IContainerMD::XAttrMap& attrmap,
const eos::common::VirtualIdentity& vid,
eos::IFileMD::XAttrMap* attrmapF = NULL, bool sysaclOnly = false);
//----------------------------------------------------------------------------
//! Enter system and user definition + identity used for ACL interpretation
//!
//! @param sysacl system acl definition string
//! 'u:|g:|egroup::{arwxom(!d)(+d)(!u)}
//! |z:{rw[o]xmc(!u)(+u)(!d)(+d)q}'
//! @param useracl user acl definition string
//! 'u:|g:|egroup::{rwxom(!d)(+d)(!u)}
//! |z:{rw[o]xmc(!u)(+u)(!d)(+d)q}'
//! @param vid virtual id to match ACL
//! @param allowUserAcl if true evaluate the user acl for permissions
//----------------------------------------------------------------------------
void Set(std::string sysacl, std::string useracl, std::string tokenacl,
const eos::common::VirtualIdentity& vid,
bool allowUserAcl = false);
//----------------------------------------------------------------------------
// Getter Functions for ACL booleans
//----------------------------------------------------------------------------
inline bool CanRead() const
{
return mCanRead;
}
inline bool CanNotRead() const
{
return mCanNotRead;
}
inline bool CanWrite() const
{
return mCanWrite;
}
inline bool CanNotWrite() const
{
return mCanNotWrite;
}
inline bool CanWriteOnce() const
{
return mCanWriteOnce;
}
inline bool CanUpdate() const
{
return mCanUpdate;
}
inline bool CanNotUpdate() const
{
return mCanNotUpdate;
}
inline bool CanBrowse() const
{
return mCanBrowse;
}
inline bool CanNotBrowse() const
{
return mCanNotBrowse;
}
inline bool CanChmod() const
{
return mCanChmod;
}
inline bool CanNotChmod() const
{
return mCanNotChmod;
}
inline bool CanChown() const
{
return mCanChown;
}
inline bool CanNotDelete() const
{
return mCanNotDelete;
}
inline bool CanDelete() const
{
return mCanDelete;
}
inline bool CanSetQuota() const
{
return mCanSetQuota;
}
inline bool HasAcl() const
{
return mHasAcl;
}
inline bool HasEgroup() const
{
return mHasEgroup;
}
//----------------------------------------------------------------------------
//! It should not have the 'i' flag to be mutable
//----------------------------------------------------------------------------
inline bool IsMutable() const
{
return mIsMutable;
}
//----------------------------------------------------------------------------
//! Has the 'a' flag - archiving permission
//----------------------------------------------------------------------------
inline bool CanArchive() const
{
return mCanArchive;
}
//----------------------------------------------------------------------------
//! Has the 'p' flag - prepare permission
//----------------------------------------------------------------------------
inline bool CanPrepare() const
{
return mCanPrepare;
}
//----------------------------------------------------------------------------
//! Extract an ACL from a token
//----------------------------------------------------------------------------
inline std::string TokenAcl(const eos::common::VirtualIdentity& vid) const;
//----------------------------------------------------------------------------
//! Return attr for sysacl
//----------------------------------------------------------------------------
inline const std::string SysAttr()
{
return sysattr;
}
//----------------------------------------------------------------------------
//! Return attr for useracl
//----------------------------------------------------------------------------
inline const std::string UserAttr()
{
return userattr;
}
inline const std::string UserAttrFile()
{
return mFileUserAcl;
}
//----------------------------------------------------------------------------
//! Return if enabled to evaluate user acls
//----------------------------------------------------------------------------
inline const bool EvalUserAttr()
{
return mEvalDirUserAcl;
}
inline const bool EvalUserAttrFile()
{
return mEvalFileUserAcl;
}
private:
bool mCanRead; ///< acl allows read access
bool mCanNotRead; ///< acl denies read access
bool mCanWrite; ///< acl allows write access
bool mCanNotWrite; ///< acl denies write access
bool mCanWriteOnce; ///< acl allows write-once access (creation, no delete)
bool mCanUpdate; ///< acl allows update of files
bool mCanNotUpdate; ///< acl denies update of files
bool mCanBrowse; ///< acl allows browsing
bool mCanNotBrowse; ///< acl allows browsing
bool mCanChmod; ///< acl allows mode change
bool mCanChown; ///< acl allows chown change
bool mCanNotDelete; ///< acl forbids deletion
bool mCanNotChmod; ///< acl forbids chmod
bool mCanDelete; ///< acl allows deletion
bool mCanSetQuota; ///< acl allows to set quota
bool mHasAcl; ///< acl is valid
bool mHasEgroup; ///< acl contains egroup rule
bool mIsMutable; ///< acl does not contain the immutable flag
bool mCanArchive; ///< acl which allows archiving
bool mCanPrepare; ///< acl which allows triggering workflows
std::string sysattr;
std::string userattr;
bool mEvalDirUserAcl;
std::string mFileUserAcl;
bool mEvalFileUserAcl;
};
EOSMGMNAMESPACE_END