Permissions manager for ACLs
Description
Competition Assessment
duplicates
relates to
SmartDraw Connector
Katalon Manual Tests (BETA)
Activity
Erin Clark June 11, 2019 at 10:01 PM
Erin Clark June 11, 2019 at 10:00 PM
We have an ACL manager now as of https://ixsystems.atlassian.net/browse/NAS-101291#icft=NAS-101291
Andrew Walker March 12, 2019 at 7:53 PM
I just merged in some middleware changes in master that gives you three important knobs related to ACLs: acl_is_trivial, getacl, setacl. To simplify user experience / mimic Windows UI behavior I have introduced two distinct representation of ACLs (simplified and advanced). The UI must allow users to view and edit ACLs using either representation.
filesystem.acl_is_trivial
<pre>
@accepts(Str('path'))
def acl_is_trivial(self, path):
</pre>
This one returns "True" if the ACL can be fully expressed by the posix mode without losing information. An example of where to use this is the "Unix" permissions editor, where we can disallow changing posix mode if filesystem.acl_is_trivial returns "False" and show an information message in the UI that users should first strip the extended ACL before attempting to alter the posix mode.
filesystem.getacl
<pre> @accepts(
Str('path'),
Bool('simplified', default=True),
)
def getacl(self, path, simplified=True):</pre>
There are two ways to view the ACL. The simplified or basic view corresponds roughly with what you see in the basic view in Windows File Explorer. The following is an example 'simple' entry:
<pre> {
"tag": "owner@",
"id": null,
"type": "ALLOW",
"perms": {
"BASIC": "FULL_CONTROL"
},
"flags": {
"BASIC": "INHERIT"
}
},
</pre>
if it is called with 'simplified=False', the resulting 'advanced' ACL entry is as follows:
<pre> {
"tag": "owner@",
"id": null,
"type": "ALLOW",
"perms": {
"READ_DATA": true,
"WRITE_DATA": true,
"APPEND_DATA": true,
"READ_NAMED_ATTRS": true,
"WRITE_NAMED_ATTRS": true,
"EXECUTE": true,
"DELETE_CHILD": true,
"READ_ATTRIBUTES": true,
"WRITE_ATTRIBUTES": true,
"DELETE": true,
"READ_ACL": true,
"WRITE_ACL": true,
"WRITE_OWNER": true,
"SYNCHRONIZE": true
},
"flags": {
"FILE_INHERIT": true,
"DIRECTORY_INHERIT": true,
"NO_PROPAGATE_INHERIT": false,
"INHERIT_ONLY": false,
"INHERITED": false
}
},
</pre>
If the perms or flags cannot be expressed as a simple entry without information loss, then the entry will appear as "OTHER":
<pre> {
"tag": "owner@",
"id": null,
"type": "ALLOW",
"perms": {
"BASIC": "OTHER"
},
"flags": {
"BASIC": "OTHER"
}
},
</pre>
The resulting ACL can be presented to users as follows:
<pre>1|'tag'|<USER/GROUP>|'perms'|'flags'|'type'
2|'tag'|<USER/GROUP>|'perms'|'flags'|'type'
3|'tag'|<USER/GROUP>|'perms'|'flags'|'type'</pre>
filesystem.getacl will return the numeric id of the user/group this should be resolved to a user or group name if possible. If the 'tag' is 'owner@'|'group@' or 'everyone@', then <USER/GROUP> field should not be visible in the UI. If one of these special tags is set, then the value of 'id' will be None.
In the simple / basic view, the text value of 'perms' and 'flags' can be displayed. In the 'advanced' view, we will probably need to present checkboxes because of the large number of entries.
filesystem.getacl
<pre> @accepts(
Str('path'),
List(
'dacl',
items=[
Dict(
'aclentry',
Str('tag', enum=['owner@', 'group@', 'everyone@', 'USER', 'GROUP']),
Int('id', null=True),
Str('type', enum=['ALLOW', 'DENY']),
Dict(
'perms',
Bool('READ_DATA'),
Bool('WRITE_DATA'),
Bool('APPEND_DATA'),
Bool('READ_NAMED_ATTRS'),
Bool('WRITE_NAMED_ATTRS'),
Bool('EXECUTE'),
Bool('DELETE_CHILD'),
Bool('READ_ATTRIBUTES'),
Bool('WRITE_ATTRIBUTES'),
Bool('DELETE'),
Bool('READ_ACL'),
Bool('WRITE_ACL'),
Bool('WRITE_OWNER'),
Bool('SYNCHRONIZE'),
Str('BASIC', enum=['FULL_CONTROL', 'MODIFY', 'READ', 'OTHER']),
),
Dict(
'flags',
Bool('FILE_INHERIT'),
Bool('DIRECTORY_INHERIT'),
Bool('NO_PROPAGATE_INHERIT'),
Bool('INHERIT_ONLY'),
Bool('INHERITED'),
Str('BASIC', enum=['INHERIT', 'NOINHERIT', 'OTHER']),
),
)
],
default=[]
),
Dict(
'options',
Bool('stripacl', default=False),
Bool('recursive', default=False),
Bool('traverse', default=False),
)
)
</pre>
The simplified representation of the ACL can be used for 'setacl' as long as 'OTHER' is not used as the permset or flagset. 'id' is the numeric ID of the User or Group. If 'tag' is set to 'owner@','group@', or 'everyone@', then the 'id' must be None.
Example with simple ACE and advanced ACE:
<pre>new_acl = [
{
'tag': 'owner@',
'id': None,
'type': 'ALLOW',
'perms': {
'BASIC': 'FULL_CONTROL'
},
'flags': {
'BASIC': 'INHERIT',
},
},
{
'tag': 'GROUP',
'id': 1000,
'type': 'ALLOW',
'perms': {
'READ_DATA': True,
'WRITE_DATA': False,
'APPEND_DATA': False,
'READ_NAMED_ATTRS': True,
'WRITE_NAMED_ATTRS': False,
'EXECUTE': True,
'DELETE_CHILD': False,
'READ_ATTRIBUTES': True,
'WRITE_ATTRIBUTES': False,
'DELETE': False,
'READ_ACL': True,
'WRITE_ACL': False,
'WRITE_OWNER': False,
'SYNCHRONIZE': False,
},
'flags': {
'FILE_INHERIT': False,
'DIRECTORY_INHERIT': False,
'NO_PROPAGATE_INHERIT': False,
'INHERIT_ONLY': False,
'INHERITED': False
},
},
]
Client().call('filesystem.setacl', '/mnt/dozer/SMB', new_acl, {'recursive':True, 'traverse':True})
</pre>
The ACL editor should present options (possibly checkboxes) to apply the ACL recursively and to traverse filesystem boundaries (we can contain the permissions change to a single ZFS dataset). Once again, this takes IDs rather than user / group names as arguments.
The 'stripacl' option will rip out extended ACL entries that are on the file. It may make more sense to present 'stripacl' as an option in the posix permissions editor alongside the message that they cannot use it because of extended entries. In this case the following may be a sensible choice for a command along with a button to recursively strip extended ACL entries:
<pre>filesystem.setacl(<path>, [], {'stripacl': True, 'recursive':True})</pre>
Sean McBride March 10, 2019 at 11:46 PM
+1 for me.
For Mac users, this would be nice, because SMB is the default sharing system these days (AFP is deprecated).
Andrew Walker December 7, 2017 at 4:14 AM
This feature has been requested by TrueNAS customer in SCM-464-66530.
Something that comes up every once in a while is the limitation of a Windows client being the default way of managing permissions when using SMB and corresponding ACLs.
It would be nice to have a permissions manager that displays currently-set permissions (for the share root) and can apply permissions recursively to the whole share (no need for more granularity than that, at first). Something about as capable as the Windows Security tab would be nice.
I'm guessing this could also be combined with the occasionally-mentioned mythical file browser, for extra granularity, if it's considered advantageous.
Definitely lower-priority than all features related to Corralpocalypse.