ACL Functions
ACL functions allow for fetching and setting Access Controls (permissions) on files.
Currently, only ‘opaque’ ACLs are supported, meaning the ACLs can only be copied, not inspected.
Description
ace_v4 struct
The ace_v4
struct returned by arcapix.fs.gpfs.clib.acl.get_nfs4_acl()
has the following fields
aceType # Allow or Deny
aceFlags # Inherit specifications, etc.
aceIFlags # GPFS Internal flags
aceMask # NFSv4 mask specification
aceWho # User/Group identification
All fields are of type int.
The aceType
field is one of: AT_ALLOW
, AT_DENY
, AT_AUDIT
, AT_ALARM
The aceFlags
field is a combination of
AF_FILE_INHERIT
AF_DIR_INHERIT
AF_NO_PROPAGATE
AF_INHERIT_ONLY
AF_SUCCESSFUL
AF_FAILED
AF_GROUP_ID
AF_INHERITED
The aceIFlags
field is either AI_SPECIAL_ID
indicating the ACE is a special (owner, group, everyone), or 0.
For convenience, the is_special()
function checks this field.
The aceMask
field indicates what permissions apply to the ACE. It is made of a combination of
AM_READ
AM_LIST_DIR
AM_WRITE
AM_ADD_FILE
AM_APPEND
AM_ADD_SUBDIR
AM_READ_NAMED
AM_WRITE_NAMED
AM_EXECUTE
AM_SEARCH
AM_DELETE_CHILD
AM_READ_ATTR
AM_WRITE_ATTR
AM_DELETE
AM_READ_ACL
AM_WRITE_ACL
AM_WRITE_OWNER
AM_SYNCHRONIZE
AM_ALL
where AM_ALL
is a shorthand for a combination of all the permissions.
In addition, the following combination aliases are provided, which roughly correspond to POSIX permissions
AM_POSIX_READ
AM_POSIX_WRITE
AM_POSIX_EXECUTE
The aceWho
flag is one of AS_OWNER
, AS_GROUP
, AS_EVERYONE
if this is a special ACE;
a group id if aceFlags
includes AF_GROUP_ID
; or else a user id.
The arcapix.fs.gpfs.clib.utils.acl.get_ace_name()
convenience function will translate this to a name.
- class arcapix.fs.gpfs.clib.acl.ace_v4(aceType=0, aceFlags=0, aceIFlags=0, aceMask=0, aceWho=0)
NFSv4 ACL entry.
- arcapix.fs.gpfs.clib.acl.copy_acl(source, dest)
Copy ACL from one file to another.
- arcapix.fs.gpfs.clib.acl.get_nfs4_acl(pathname)
Get NFSv4 ACL for a path.
- arcapix.fs.gpfs.clib.acl.getacl(source)
Get a file’s acls.
- Parameters
source (str) – path to a file to get acls from.
- Returns
opaque_acl
object holding the file’s acls
- arcapix.fs.gpfs.clib.acl.is_group(ace)
Returns whether an ACE applies to a group.
In that case, the ACE
aceWho
is a group id
- arcapix.fs.gpfs.clib.acl.is_special(ace)
Returns whether the ACE is a special.
Special ACEs apply to the file owner user, owner group, or everyone.
The specific type is deferminted by the ACE
aceWho
attributee.g.
>>> is_special(ace) and (ace.aceWho == AS_OWNER) True
- arcapix.fs.gpfs.clib.acl.is_user(ace)
Returns whether an ACE applies to a user.
In that case, the ACE
aceWho
is a user id
- arcapix.fs.gpfs.clib.acl.put_nfs4_acl(pathname, acl)
Put an NFSv4 ACL for a path.
- Parameters
The ACL can either be from
get_nfs4_acl()
or manually constructed.Note
For copying ACLs between files,
copy_acl()
is more efficient.For appending an ACE to a file,
arcapix.fs.gpfs.clib.utils.acl.append_nfs4_aces()
if more efficient.
Examples
Copy ACLs from one file to another
>>> from arcapix.fs.gpfs.clib.acl import copy_acl
>>>
>>> copy_acl('/mmfs1/test01.txt', '/mmfs1/test02.txt')
Check if file owner has read and write permission
>>> from arcapix.fs.gpfs.clib.acl import get_nfs4_acl
>>> from arcapix.fs.gpfs.clib.acl import is_special, AS_OWNER
>>> from arcapix.fs.gpfs.clib.acl import AT_ALLOW, AM_READ, AM_WRITE
>>>
>>> acl = get_nfs4_acl("/mmfs1/test")
>>>
>>> # check first entry is the ACE for the file owner
>>> # (this is typically true, but not necessarily)
>>> assert is_special(acl[0]) and acl[0].aceWho == AS_OWNER
>>>
>>> # check it is an 'allow' ACE
>>> # if it was deny we would have to invert the check
>>> assert acl[0].aceType == AT_ALLOW
>>>
>>> # check the mask allows read/write
>>> assert acl[0].aceMask & (AM_READ | AM_WRITE)
List all ACEs and whether execute permission is granted
>>> from arcapix.fs.gpfs.clib.acl import get_nfs4_acl, AT_ALLOW, AM_EXECUTE
>>> from arcapix.fs.gpfs.clib.utils.acl import get_ace_name
>>>
>>> acl = get_nfs4_acl("/mmfs1/test.bin")
>>>
>>> for ace in acl:
... if ace.aceType == AT_ALLOW:
... can_exec = bool(ace.aceMask & AM_EXECUTE)
... else:
... can_exec = not bool(ace.aceMask & AM_EXECUTE)
... type, name = get_ace_name(ace)
... print("%s:%s - %s", type, name, can_exec)
...
special:owner@ - True
special:group@ - False
special:everyone@ - False
group:admin - True
Add read permission to all existing ACL entries
Note - this ignores whether the existing ACEs are allow or deny. If an ACE were deny, this would take away read permission
>>> from arcapix.fs.gpfs.clib.acl import get_nfs4_acl, put_nfs4_acl, AM_READ
>>>
>>> # get the current ACL
>>> acl = get_nfs4_acl('/mmfs1/test')
>>>
>>> # add read permission to each ACE
>>> for ace in acl:
... ace.aceMask |= AM_READ
...
>>> # apply the updated ACL
>>> put_acl('/mmfs1/test', acl)
Remove the last entry from an ACL
>>> from arcapix.fs.gpfs.clib.acl import get_nfs4_acl, put_nfs4_acl
>>>
>>> # get the current ACL
>>> acl = get_nfs4_acl('/mmfs1/test')
>>>
>>> # drop the last entry
>>> acl.pop()
>>>
>>> # apply the updated ACL
>>> put_acl('/mmfs1/test', acl)