s4:python/ntacl: add fsacl_child_sd() function
authorStefan Metzmacher <metze@samba.org>
Sat, 1 Dec 2012 13:36:21 +0000 (14:36 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 18 Feb 2019 10:31:19 +0000 (11:31 +0100)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
python/samba/ntacls.py

index fa2ce0216001f4bc150adda586e3e7d8d4b3fc95..63a7f8d84a15be0a3b8d1fa9408ac56776a5b205 100644 (file)
@@ -627,3 +627,87 @@ def backup_restore(src_tarfile_path, dst_service_path, samdb_conn, smb_conf_path
                         dst_file.write(data)
 
     shutil.rmtree(tempdir)
+
+
+def fsacl_child_sd(parent_sddl, domain_sid, owner_sid, group_sid, container=True, as_sddl=True):
+    """
+
+    This function takes an the SDDL representation of a filesystem
+    ACL and return the SDDL representation of this ACL adapted
+    for child files/directories. It's used for Policy object provision
+    """
+    parent_sd = security.descriptor.from_sddl(parent_sddl, domain_sid)
+    fdescr = security.descriptor()
+    fdescr.owner_sid = owner_sid
+    fdescr.group_sid = group_sid
+    fdescr.type = parent_sd.type
+    fdescr.type |= security.SEC_DESC_DACL_AUTO_INHERITED
+    fdescr.revision = parent_sd.revision
+    aces = parent_sd.dacl.aces
+    for i in range(0, len(aces)):
+        ace = aces[i]
+        ace2 = None
+
+        if ace.type == security.SEC_ACE_TYPE_ACCESS_ALLOWED:
+            pass
+        elif ace.type == security.SEC_ACE_TYPE_ACCESS_DENIED:
+            pass
+        else:
+            continue
+
+        inherit_ace = False
+        if not container:
+            if ace.flags & security.SEC_ACE_FLAG_OBJECT_INHERIT:
+                inherit_ace = True
+        else:
+            if ace.flags & security.SEC_ACE_FLAG_CONTAINER_INHERIT:
+                inherit_ace = True
+            if ((ace.flags & security.SEC_ACE_FLAG_OBJECT_INHERIT) and \
+               not (ace.flags & security.SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)):
+                inherit_ace = True
+
+        if not inherit_ace:
+            continue
+
+        if not container:
+            ace.flags = 0;
+        else:
+            ace.flags &= ~security.SEC_ACE_FLAG_INHERIT_ONLY
+            if not (ace.flags & security.SEC_ACE_FLAG_CONTAINER_INHERIT):
+                ace.flags |= security.SEC_ACE_FLAG_INHERIT_ONLY
+            ace.flags &= ~security.SEC_ACE_FLAG_INHERIT_ONLY
+            if ace.flags & security.SEC_ACE_FLAG_NO_PROPAGATE_INHERIT:
+                ace.flags = 0;
+
+        ace.flags |= security.SEC_ACE_FLAG_INHERITED_ACE
+
+        if str(ace.trustee) == security.SID_CREATOR_OWNER:
+            ace2 = ace
+
+            ace = security.ace()
+            ace.type = ace.type
+            ace.flags = ace.flags
+            ace.access_mask = ace.access_mask
+            ace.trustee = owner_sid
+
+            ace2.flags |= security.SEC_ACE_FLAG_INHERIT_ONLY
+
+        if str(ace.trustee) == security.SID_CREATOR_GROUP:
+            ace2 = ace
+
+            ace = security.ace()
+            ace.type = ace.type
+            ace.flags = ace.flags
+            ace.access_mask = ace.access_mask
+            ace.trustee = group_sid
+
+            ace2.flags |= security.SEC_ACE_FLAG_INHERIT_ONLY
+
+        fdescr.dacl_add(ace)
+        if container and ace2 is not None:
+            fdescr.dacl_add(ace2)
+
+    if not as_sddl:
+        return fdescr
+
+    return fdescr.as_sddl(domain_sid)