API Documentation

Package nfs4acl

A library for manipulating NFSv4 style ACLs by calling the native ACL libraries.

Author:

Franz Glasner

Company:

FELDMANN media group AG

Copyright:
  • © 2018 FELDMANN media group AG

  • © 2018 Franz Glasner

License:

GNU Lesser General Public License v2.1 or later (LGPLv2.1+). See LGPL-2.1-or-later.txt for details.

ID:

@(#) $Header: nfs4acl/__init__.py 5c1ddc82db26 2026-06-10 11:04:48 +0200 fzglas.hg public $

This module contains all the public types the user will probably want to work with.

These types are implemented in platform dependent sub-packages and aliased in nfs4acl.

For FreeBSD these are the types from nfs4acl.freebsd.acl:

nfs4acl.PLATFORM = 'freebsd'

The name of the platform dependent module being used

Module nfs4acl.const

This module contains all public constants. Its content (either attributes and values) is platform dependent.

On FreeBSD this is an alias for nfs4acl.freebsd.const.

Module nfs4acl.compat

A small compatibility shim for Python2 and Python3 compatibility.

nfs4acl.compat.b(s, encoding='utf_8')
nfs4acl.compat.bfs(s, encoding='utf-8')
nfs4acl.compat.u(s, encoding='utf_8')

Module nfs4acl.getacl

The implementation of a getfacl(1) alike.

Differences to getfacl(1) are:

  • Handle only NFSv4 ACLs – no POSIX ACLs

  • Can do recursive file tree traversal with flexible symbolic link handling

See also

the manual page

Usage: getacl [options] [file …]

Options:

-H, --half-logical

If option -R is specified, follow symbolic links named on the command line only. Symbolic links encountered during traversal are not followed.

-h, --no-dereference

If the command line target of the operation is a symbolic link, return the ACL from the symbolic link itself rather than following the link.

--help

Print this help and exit.

-i

Append the numerical ID at the end of each ACL entry containing user or group names.

-L, --logical

If option -R is specified, all symbolic links are followed.

-n, --numeric

Display user and group IDs numerically rather than converting to a user or group name.

-P, --physical

If option -R is specified, no symbolic links are followed. This is the default.

-q, --omit-header

Do not write commented information about file name and ownership.

-R, --recursive

Operate recursively on files and directories.

-v

Display permissions and flags in a verbose form.

--version

Print the version number and exit.

-x

Do not traverse file system mount points.

The following operand is available:

file

A pathname of a file whose ACL shall be retrieved. If file is not specified, or a file is specified as -, then getacl reads a list of pathnames, each terminated by one newline character, from the standard input.

nfs4acl.getacl.main()

The main entry point

Module nfs4acl.utils

Some utility and helper classes and functions.

class nfs4acl.utils.SingletonType

Metaclass for implementing a singleton.

Calls __init__() from the singleton class only once. Just overriding its __new__ calls it always.

Package nfs4acl.freebsd

Sub-package that contains the implemention of NFSv4 ACLs using the FreeBSD security API.

FreeBSD implements NFSv4 style ACLs on its native filesystems ZFS and UFS.

The main references are:

Module nfs4acl.freebsd.acl

The ACL implementation for NFSv4 ACLs on FreeBSD.

Note

The public content of this module is meant to be accessed by clients via its aliases in nfs4acl.

Todo

Platform-independent pickling style.

Is platform-independency really required? Use some normalized text representation for this instead (e.g. using getfacl(1) and friends)?

class nfs4acl.freebsd.acl.ACL(file=None, fd=None, follow_symlink=True, text=None, acl=None, _attach_ptr=None, _acldll=None, _num_entries=None)

Represent an NFSv4 ACL.

An ACL is its own context manager because it must be freed with close() to release any OS resources associated with the ACL.

After initialization an ACL has no connections to filesystem objects. It exists in memory only. You have to call applyto() to apply the ACL to a file (either the same as used in the constructor or another one).

An ACL is its own iterator and iterates over all its entries.

An ACL in boolean context evaluates to False if there are no entries and to True otherwise. If the ACL is closed it evaluates to False also.

The pickle protocol is supported. But because of the native interface: only complete ACLs can be pickled, not just individual entries. The qualifier is pickled as ID number type only. This may or may not be what you want.

Parameters:
  • file (str) – create an ACL representing the access ACL of the specified file

  • fd (int) – create an ACL representing the access ACL of the given file descriptor

  • text (str) – create an ACL from a textual description

  • acl (ACL) – create a copy of an existing ACL instance

  • follow_symlink (bool) – if False, act on a symlink rather than its target, if the target of the item is a symlink

Only one of file, fd, text or acl can be given.

If no parameters are passed, an empty ACL will be created; this makes sense only when your OS supports ACL modification, otherwise the ACL won’t be useful.

INIT_COUNT = 254

The default number of entries to allocate at least when creating a new empty ACL

__getstate__()

Return the ACL as platform-dependent-picklable state

__setstate__(state)

Instantiate when unpickling from pickled platform-dependent state state

applyto(item, follow_symlink=True)

Set an NFSv4 ACL for a file.

Parameters:
  • item – the filesystem object on which to act; it be a path string, a file-like with a item.fileno() or a file descriptor

  • follow_symlink (bool) – the method acts on a symlink rather than its target, if the target of the item is a symlink

__enter__()

Behave as its own context manager

__exit__(*args, **kwds)

Behave as its own context manager: leave the context and call close() to properly free any resources

close()

Free the OS resources associated with the ACL

property is_closed

Return whether the ACL has been already closed

check_not_closed()

Check that the ACL is not closed; otherwise raise a proper ValueError exception.

clear()

Delete all entries from the current ACL

append(entry=None)

Append a new Entry to the ACL and return it.

This is a convenience function to create a new Entry and append it to the ACL. If a parameter of type Entry instance is given, the entry will be a copy of that one (as if copied with Entry.copy()), otherwise, the new entry will be empty.

Note

The source entry (which effectively is a pointer) may become invalid by creating a new entry because the ACL may be relocated. So this method tries to be safe and makes a copy into a completely new and independent ACL beforehand.

delete_entry(item)

Delete the ACL entry in item from the ACL.

Parameters:

item – the entry to delete to; it can be an Entry that belongs to self or an int that will be interpreted as zero-based index position of the ACE to be deleted

stripped()

Return a new ACL with extended entries stripped

is_trivial()

Determine whether the ACL is trivial.

An ACL is trivial if it can be fully expressed as a file mode without losing any access rules.

For NFSv4 ACLs, an ACL is trivial if it is identical to the ACL generated by stripped().

Return type:

True or False

valid(file=None, fd=None, follow_symlink=True)

Validate an ACL.

Allow an ACL to be checked in the context of a specific file system object.

Parameters:
  • file (str) – validate the ACL against the file specified with its name

  • fd (int) – validate the ACL against the file system object specified with its descriptor

Return type:

True or False

Exactly one of file or fd must be given.

On FreeBSD NFSv4 ACLs can be checked only within the context of a filesystem object.

__iter__()

Iterate over all ACL entries.

An ACL is its own iterator and yields all entries in order.

__copy__()

Return a duplicate of the ACL.

Implementation of the copy protocol for copy.copy().

__eq__(other)

Implement the logical == operator.

Parameters:

other (ACL or str) – the thing to compare with

Converts self and other into a string with numeric ids and compares the results. If other is already in string form be sure to create it using numeric ids; when being generated the text representation is created with .to_any_text(options=ACL_TEXT_NUMERIC_IDS).

Todo

Normalize the string representation before comparing: for each line: strip white space et al.

__ne__(other)

Implement the logical != operator.

Parameters:

other (ACL or str) – the thing to compare with

Converts self and other into a string with numeric ids and compares the results. If other is already in string form be sure to create it using numeric ids; when beging generated the text representation is created with .to_any_text(options=ACL_TEXT_NUMERIC_IDS).

__hash__ = None

Hashing is explicitely not supported because an ACL is mutable

__bool__()

Evaluate in a boolean context: an ACL in boolean context evaluates to False if there are no entries and to True otherwise.

__bytes__()

PY3 method to convert into a bytes representation

__unicode__()

PY2 method to convert into a unicode representation

__str__()

Return a native string representation of the ACL using the native “acl_to_text()”

to_any_text(prefix='', separator='\n', options=0)

Return a custom text representation of the ACL.

Parameters:
  • prefix (str) – optional string that will be pre-pended to all lines.

  • separator (str) – a string that will be used to separate the entries in the ACL.

  • options (int) –

    a combination (with or’ing) of the following values:

For NFSv4 ACLs the format of the text string shall be the compact form, unless the ACL_TEXT_VERBOSE flag is given.

__repr__()

Return repr(self).

class nfs4acl.freebsd.acl.Entry(acl, pos=-1, _attach_ptr=None, _attach_generation=None)

Represents an NFSv4 entry in an ACL (aka ACE).

A newly created ACE is initialized in the following ways: the ACE tag_type component contains ACL_UNDEFINED_TAG, the qualifier component contains ACL_UNDEFINED_ID, and the set of permissions has no permissions enabled. Any existing ACL entry descriptors that refer to entries in the ACL continue to refer to those entries.

In boolean context an entry evaluates to True iff its parent ACL is not closed.

Create a new ACL entry (ACE) within ACL acl at position pos.

Parameters:
  • acl (ACL) – the ACL this ACE belongs to

  • pos (int) – optional position where to create the new ACL; if the value is -1 then the new entry will be appended at the end

copy(src)

Copy the content of the ACL entry in src into self.

The source entry can be one of the same ACL or belong to another ACL. Both entries remain independent afterwards.

delete()

Delete this ACL entry from the ACL

property parent

The parent ACL of this entry

property tag_type

The tag type of the current entry as int.

Together with the qualifier field this field controls for whom this entry describes access permissions.

Valid values are:

  • ACL_USER_OBJ

    Permissions apply to file owner (aka user@)

  • ACL_USER

    Permissions apply to additional user specified by qualifier

  • ACL_GROUP_OBJ

    Permissions apply to file group (aka group@)

  • ACL_GROUP

    Permissions apply to additional group specified by qualifier

  • ACL_MASK

    Permissions specify mask (not to be used on NFSv4 ACLs)

  • ACL_OTHER

    Permissions apply to other (not to be used on NFSv4 ACLs)

  • ACL_OTHER_OBJ

    Same as ACL_OTHER

  • ACL_EVERYONE

    Permissions apply to virtually everyone (aka everyone@)

property qualifier

The qualifier (aka principal) of the entry as int.

This is the id of a user or group for whom this entry describes access permissions.

If the tag_type is ACL_USER, this should be a user id. If the tag type if ACL_GROUP, this should be a group id.

On a newly created entry this is ACL_UNDEFINED_ID.

property entry_type

Get the NFSv4 entry type of the entry as int.

Valid values are:

Not yet supported are:

property permset

Return a Permset instance that operates on the current entry.

This field defines what kind of access the process matching this entry has for accessing the associated file.

Note

When operating only on the permset of the ACE the setter is not needed because the returned Permset operates directly on the entry you got the permset from.

The setter can be used to copy a permset as a whole from another one (of the same or another ACL).

property flagset

Return a Flagset instance that operates on the current entry.

Flage are used to control and/or view the inheritance of ACLs.

Note

When operating only on the flagset of the ACE the setter is not needed because the returned Flagset operates directly on the entry you got the flagset from.

The setter can be used to copy a flagset as a whole from another one (of the same or another ACL).

__bool__()

An Entry evaluates to True iff its parent ACL is not yet closed and the number of entries has not changed since the creation of self.

check_valid()

Raise a ValueError exception iff the entry evals to False.

So – this method passes if the parent ACL is not closed and the current entry’s generation number matches the generation number of the parent ACL.

__eq__(other)

Logical equality check for an ACE: all of its fields must be equal.

__ne__(other)

Logical inequality check for an ACE: if any of its fields differs then the complete entry differs

__hash__ = None

Hashing is explicitely not supported: the type is mutable

__str__()

Return a native string representation of the entry.

Simulate “acl_to_text()” for an entry only.

__repr__()

Return repr(self).

class nfs4acl.freebsd.acl.Permset(entry)

Type which represents the permission set in an ACL entry.

An instance of this class is just a descriptor into the permset of the entry. Thus all operations operate directly on the entry.

In boolean context a Permset evaluates to True iff any of its permission bits is set.

Because an instance of this class is mutable hashing is explicitely not supported.

Parameters:

entry (Entry) – the ACE this permission set belongs to.

property parent

The parent ACL entry

add(perm)

Add a permission to the permission set.

This function adds the permission contained in the argument perm to the permission set. An attempt to add a permission that is already contained in the permission set is not considered an error.

Only a single permission can be added per call. FreeBSD checks this.

For NFSv4 ACLs, valid values are:

clear()

Clear all permissions from the permission set

delete(perm)

Delete a permission from the permission set.

This function deletes the permission contained in the argument perm from the permission set. An attempt to delete a permission that is not contained in the permission set is not considered an error.

For the valid permissions see add().

test(perm)

Test if a permission exists in the permission set.

For the permissions see add().

__int__()

Convert the permission set losslessly to an int

__index__()

Convert losslessly to an int and support bin(), hex() or oct()

__eq__(other)

Implement self != other by value

__ne__(other)

Implement self != other by value

__hash__ = None

Hashing is explcitely not supported: the type is not immutable

__bool__()

A Permset evaluates to True iff any of its permission bits is set.

__str__()

Return str(self).

__repr__()

Return repr(self).

class nfs4acl.freebsd.acl.Flagset(entry)

Type which represents the flagset in an NSFv4 ACL entry.

An instance of this class is just a descriptor into the flagset of the entry. Thus all operations operate directly on the entry.

In boolean context a Permset evaluates to True iff any of its flag bits is set.

This is exactly the behaviour of Permset.

Because an instance of this class is mutable hashing is explicitely not supported.

Parameters:

entry (Entry) – the ACE this flagset belongs to.

property parent

The parent ACL entry

add(flag)

Add a flag to the flagset.

This function adds the Flag contained in the argument flag to the flag set.

It is not considered an error to attempt to add flags that already exist in the flagset.

Valid values are:

clear()

Clear all NFSv4 ACL flags from the current flagset

delete(flag)

Delete a NFSv4 flag from the flagset.

An attempt to delete a permission that is not contained in the permission set is not considered an error.

For the valid flags see add()

test(flag)

Test if a flag exists in the flagset.

For the valid flags see add().

__int__()

Get the flagset as native int

__index__()

Convert loslessly to an int and support bin(), hex() or oct()

__eq__(other)

Implement self == other by value

__ne__(other)

Implement self != other by value

__hash__ = None

Hashing is explcitely not supported: the type is not immutable

__bool__()

A Flagset evaluates to True iff any of its flag bits is set.

__str__()

Return str(self).

__repr__()

Return repr(self).

Module nfs4acl.freebsd.const

FreeBSD specific public constants from the /usr/include/sys/acl.h header.

Note

This module is meant to be accessed by clients via its alias nfs4acl.const.

nfs4acl.freebsd.const.ACL_UNDEFINED_TAG = 0

A newly created entry has this tag

nfs4acl.freebsd.const.ACL_USER_OBJ = 1

Permissions apply to file owner (aka owner@)

nfs4acl.freebsd.const.ACL_USER = 2

Permissions apply to additional user specified by qualifier

nfs4acl.freebsd.const.ACL_GROUP_OBJ = 4

Permissions apply to file group (aka group@)

nfs4acl.freebsd.const.ACL_GROUP = 8

Permissions apply to additional group specified by qualifier

nfs4acl.freebsd.const.ACL_MASK = 16

Permissions specify mask.

Invalid for NFSv4 ACLs. Do not use ACL_MASK.

nfs4acl.freebsd.const.ACL_OTHER = 32

Permissions apply to other

nfs4acl.freebsd.const.ACL_OTHER_OBJ = 32

Same as ACL_OTHER

nfs4acl.freebsd.const.ACL_EVERYONE = 64

Permissions apply to everyone (aka everyone@)

nfs4acl.freebsd.const.ACL_UNDEFINED_ID = -1

A newly created ACL has this principal (qualifier) which is not a real id on the system.

For entries other than ACL_USER and ACL_GROUP, this field should be set to ACL_UNDEFINED_ID.

nfs4acl.freebsd.const.ACL_ENTRY_TYPE_ALLOW = 256

allow type entry.

Allow principal (qualifier) to perform actions requiring permissions.

nfs4acl.freebsd.const.ACL_ENTRY_TYPE_DENY = 512

deny type entry.

Deny principal (qualifier) from performing actions requiring permissions.

nfs4acl.freebsd.const.ACL_ENTRY_TYPE_AUDIT = 1024

Audit.

Log any attemted access by the principal (qualifier) which requires permissions. Requires one or both of the successful-access and failed-access flags.

Not yet supported on FreeBSD.

nfs4acl.freebsd.const.ACL_ENTRY_TYPE_ALARM = 2048

Alarm.

Generate a system alarm at any attempted access by the principal (qualifier) which requires permissions. Requires one or both of the successful-access and failed-access flags.

Not yet supported on FreeBSD

nfs4acl.freebsd.const.ACL_EXECUTE = 1

Execute (files) / change-directory (directories)

nfs4acl.freebsd.const.ACL_READ_DATA = 8

Read-data (files) / list-directory (directories)

nfs4acl.freebsd.const.ACL_LIST_DIRECTORY = 8

The same as ACL_READ_DATA

nfs4acl.freebsd.const.ACL_WRITE_DATA = 16

Write-data (files) / create-file (directories)

nfs4acl.freebsd.const.ACL_ADD_FILE = 16

The same as ACL_WRITE_DATA

nfs4acl.freebsd.const.ACL_APPEND_DATA = 32

Append-data (files) / create-subdirectory (directories)

nfs4acl.freebsd.const.ACL_ADD_SUBDIRECTORY = 32

The same as ACL_APPEND_DATA

nfs4acl.freebsd.const.ACL_READ_NAMED_ATTRS = 64

Read the named attributes of the file/directory.

Ignored on FreeBSD.

nfs4acl.freebsd.const.ACL_WRITE_NAMED_ATTRS = 128

Write the named attributes of the file/directory.

Ignored on FreeBSD.

nfs4acl.freebsd.const.ACL_DELETE_CHILD = 256

Remove a file or subdirectory from within the given directory (directories only)

nfs4acl.freebsd.const.ACL_READ_ATTRIBUTES = 512

Read the attributes of the file/directory

nfs4acl.freebsd.const.ACL_WRITE_ATTRIBUTES = 1024

Write the attributes of the file/directory

nfs4acl.freebsd.const.ACL_DELETE = 2048

Delete the file/directory this ACL is placed on.

Some servers will allow a delete to occur if either this permission is set in the file/directory or if the delete-child permission is set in its parent direcory.

nfs4acl.freebsd.const.ACL_READ_ACL = 4096

Allow to read the file/directory NFSv4 ACL

nfs4acl.freebsd.const.ACL_WRITE_ACL = 8192

Allow to write the file/directory NFSv4 ACL and the file mode

nfs4acl.freebsd.const.ACL_WRITE_OWNER = 16384

Allow change of ownership of the file or directory

nfs4acl.freebsd.const.ACL_SYNCHRONIZE = 32768

Allow clients to use synchronous I/O with the server.

Ignored on FreeBSD.

nfs4acl.freebsd.const.NFS4_STR_PERM_NAMES = [(8, 'read_data', 'r'), (8, 'list_directory', None), (16, 'write_data', 'w'), (16, 'add_file', None), (1, 'execute', 'x'), (32, 'append_data', 'p'), (32, 'add_subdirectory', None), (256, 'delete_child', 'D'), (2048, 'delete', 'd'), (512, 'read_attributes', 'a'), (1024, 'write_attributes', 'A'), (64, 'read_xattr', 'R'), (128, 'write_xattr', 'W'), (4096, 'read_acl', 'c'), (8192, 'write_acl', 'C'), (16384, 'write_owner', 'o'), (32768, 'synchronize', 's'), (65529, 'full_set', ''), (40953, 'modify_set', ''), (4680, 'read_set', ''), (1200, 'write_set', '')]

The long and short descriptions for the valid permissions in a Permset in the canonical order of their output in the text representation

nfs4acl.freebsd.const.ACL_ENTRY_FILE_INHERIT = 1

Newly-created files will inherit the ACE, minus its inheritance flags. Newly-created subdirectories will inherit the ACE; if directory-inherit is not also specified in the parent ACE, inherit-only will be added to the inherited ACE.

nfs4acl.freebsd.const.ACL_ENTRY_DIRECTORY_INHERIT = 2

Newly created subdirectories will inherit the ACE

nfs4acl.freebsd.const.ACL_ENTRY_NO_PROPAGATE_INHERIT = 4

Newly-created subdirectories will inherit the ACE, minus its inheritance flags.

nfs4acl.freebsd.const.ACL_ENTRY_INHERIT_ONLY = 8

The ACE is not considered in permissions checks, but it is heritable; however, the inherit-only flag is stripped from inherited ACEs.

nfs4acl.freebsd.const.ACL_ENTRY_SUCCESSFUL_ACCESS = 16

Trigger an alarm/audit when the principal (qualifier) is allowed to perform an action covered by permissions (only valid for AUDIT and ALARM type ACEs)

nfs4acl.freebsd.const.ACL_ENTRY_FAILED_ACCESS = 32

Trigger an alarm/audit when the principal (qualifier) is prevented from performing an action covered by permissions (only valid for AUDIT and ALARM type ACEs)

nfs4acl.freebsd.const.ACL_ENTRY_INHERITED = 128

Inherited from parent.

This flag is set on an ACE that has been inherited from its parent.

It may also be set programmatically, and is valid on both files and directories.

nfs4acl.freebsd.const.NFS4_STR_FLAG_NAMES = [(1, 'file_inherit', 'f'), (2, 'dir_inherit', 'd'), (8, 'inherit_only', 'i'), (4, 'no_propagate', 'n'), (16, 'successfull_access', 'S'), (32, 'failed_access', 'F'), (128, 'inherited', 'I')]

The long and short descriptions for the valid flags in a Flagset in the canonical order of their output in the text representation

nfs4acl.freebsd.const.ACL_TEXT_VERBOSE = 1

Format ACL using verbose form

nfs4acl.freebsd.const.ACL_TEXT_NUMERIC_IDS = 2

Do not resolve IDs into user or group names

nfs4acl.freebsd.const.ACL_TEXT_APPEND_ID = 4

In addition to user and group names, append numeric IDs

Module nfs4acl.freebsd.types

Definitions of low-level types to access the native ACL library.

nfs4acl.freebsd.types.uid_t

alias of c_uint

nfs4acl.freebsd.types.gid_t

alias of c_uint

nfs4acl.freebsd.types.acl_tag_t

alias of c_uint

nfs4acl.freebsd.types.acl_perm_t

alias of c_uint

nfs4acl.freebsd.types.acl_entry_type_t

alias of c_ushort

nfs4acl.freebsd.types.acl_flag_t

alias of c_ushort

nfs4acl.freebsd.types.acl_type_t

alias of c_int

nfs4acl.freebsd.types.acl_permset_t

alias of LP_c_int

nfs4acl.freebsd.types.acl_flagset_t

alias of LP_c_ushort

nfs4acl.freebsd.types.acl_entry_t

alias of c_void_p

nfs4acl.freebsd.types.acl_t

alias of c_void_p

Module nfs4acl.freebsd.ffi

The low-level call interface to the native FreeBSD ACL library in its libc.

All the heavy interaction with the ctypes package is done here.