[PATCH 1/2] ntdll: Implement RtlDefaultNpAcl

Patrick Hibbs hibbsncc1701 at gmail.com
Thu Jun 24 15:06:44 CDT 2021


Signed-off-by: Patrick Hibbs <hibbsncc1701 at gmail.com>
---
 dlls/ntdll/sec.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 169 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/sec.c b/dlls/ntdll/sec.c
index eccfc82ce8c..448b0b7def6 100644
--- a/dlls/ntdll/sec.c
+++ b/dlls/ntdll/sec.c
@@ -1721,11 +1721,178 @@ NTSTATUS WINAPI RtlConvertToAutoInheritSecurityObject(
 
 /******************************************************************************
  * RtlDefaultNpAcl (NTDLL.@)
+ *
+ *  Constructs a default ACL with the following entries:
+ *      Local System: Full Control
+ *      Administrators: Full Control
+ *      World: Read Only
+ *      Anonymous: Read Only
+ *      Owner: Full Control
+ *
+ *      'Owner' is determined by the current effective
+ *      thread token's default owner. (Or process token if
+ *      the thread token cannot be retrieved.)
+ *
+ *      Returns STATUS_SUCCESS if successful.
+ *      Generates EXCEPTION_ACCESS_VIOLATION if pAcl is NULL.
  */
 NTSTATUS WINAPI RtlDefaultNpAcl(PACL *pAcl)
 {
-    FIXME("%p - stub\n", pAcl);
+    PACL new_acl = NULL;
+    PSID new_sid = NULL;
+    DWORD acl_length = 0;
+    ULONG owner_sid_length = 0;
+    PTOKEN_OWNER owner = NULL;
+    HANDLE token = NULL;
+    SID_IDENTIFIER_AUTHORITY local_auth = {SECURITY_NT_AUTHORITY};
+    SID_IDENTIFIER_AUTHORITY world_auth = {SECURITY_WORLD_SID_AUTHORITY};
+    NTSTATUS ret;
+
+    TRACE("pAcl=%p\n", pAcl);
 
     *pAcl = NULL;
-    return STATUS_SUCCESS;
+
+    new_sid = RtlAllocateHeap(GetProcessHeap(), 0, SECURITY_MAX_SID_SIZE);
+    if (new_sid)
+    {
+        ret = NtOpenThreadToken(GetCurrentThread(),
+                                TOKEN_QUERY,
+                                TRUE,
+                                &token);
+        if (ret == STATUS_NO_TOKEN)
+        {
+            ret = NtOpenProcessToken(GetCurrentProcess(),
+                                     TOKEN_QUERY,
+                                     &token);
+            if (!NT_SUCCESS(ret))
+            {
+                RtlFreeHeap(GetProcessHeap(), 0, new_sid);
+                return ret;
+            }
+        }
+
+        /* Get the length of the owner's SID. */
+        ret = NtQueryInformationToken(token,
+                                      TokenOwner,
+                                      NULL,
+                                      0,
+                                      &owner_sid_length);
+        if (ret == STATUS_BUFFER_TOO_SMALL)
+        {
+            owner = RtlAllocateHeap(GetProcessHeap(), 0, owner_sid_length);
+            if (owner)
+            {
+                /* Actually get the owner's SID. */
+                ret = NtQueryInformationToken(token,
+                                              TokenOwner,
+                                              owner,
+                                              owner_sid_length,
+                                              &owner_sid_length);
+                if (NT_SUCCESS(ret))
+                {
+                    acl_length = sizeof(ACL) +
+                        (5 * sizeof(ACCESS_ALLOWED_ACE)) +
+                        RtlLengthRequiredSid(1) +   /* Local System */
+                        RtlLengthRequiredSid(2) +   /* Administrators */
+                        RtlLengthRequiredSid(1) +   /* World */
+                        RtlLengthRequiredSid(1) +   /* Anonymous */
+                        RtlLengthSid(owner->Owner); /* Owner */
+
+                    new_acl = RtlAllocateHeap(GetProcessHeap(), 0, acl_length);
+                    if (new_acl)
+                    {
+                        ret = RtlCreateAcl(new_acl, acl_length, MIN_ACL_REVISION);
+                        if (NT_SUCCESS(ret))
+                        {
+                            ret = RtlInitializeSid(new_sid,
+                                                   &local_auth,
+                                                   1);
+                            if (NT_SUCCESS(ret))
+                            {
+                                *RtlSubAuthoritySid(new_sid, 0) = SECURITY_LOCAL_SYSTEM_RID;
+                                ret = RtlAddAccessAllowedAce(new_acl,
+                                                             MIN_ACL_REVISION,
+                                                             GENERIC_ALL,
+                                                             new_sid);
+                                if (NT_SUCCESS(ret))
+                                {
+                                    ret = RtlInitializeSid(new_sid,
+                                                           &local_auth,
+                                                           2);
+                                    if (NT_SUCCESS(ret))
+                                    {
+                                        *RtlSubAuthoritySid(new_sid, 0) = SECURITY_BUILTIN_DOMAIN_RID;
+                                        *RtlSubAuthoritySid(new_sid, 1) = DOMAIN_ALIAS_RID_ADMINS;
+                                        ret = RtlAddAccessAllowedAce(new_acl,
+                                                                     MIN_ACL_REVISION,
+                                                                     GENERIC_ALL,
+                                                                     new_sid);
+                                        if (NT_SUCCESS(ret))
+                                        {
+                                            ret = RtlInitializeSid(new_sid,
+                                                                   &world_auth,
+                                                                   1);
+                                            if (NT_SUCCESS(ret))
+                                            {
+                                                *RtlSubAuthoritySid(new_sid, 0) = SECURITY_WORLD_RID;
+                                                ret = RtlAddAccessAllowedAce(new_acl,
+                                                                             MIN_ACL_REVISION,
+                                                                             GENERIC_READ,
+                                                                             new_sid);
+                                                if (NT_SUCCESS(ret))
+                                                {
+                                                    ret = RtlInitializeSid(new_sid,
+                                                                           &local_auth,
+                                                                           1);
+                                                    if (NT_SUCCESS(ret))
+                                                    {
+                                                        *RtlSubAuthoritySid(new_sid, 0) = SECURITY_ANONYMOUS_LOGON_RID;
+                                                        ret = RtlAddAccessAllowedAce(new_acl,
+                                                                                     MIN_ACL_REVISION,
+                                                                                     GENERIC_READ,
+                                                                                     new_sid);
+                                                        if (NT_SUCCESS(ret))
+                                                        {
+                                                            ret = RtlAddAccessAllowedAce(new_acl,
+                                                                                         MIN_ACL_REVISION,
+                                                                                         GENERIC_ALL,
+                                                                                         owner->Owner);
+                                                            if (NT_SUCCESS(ret))
+                                                            {
+                                                                *pAcl = new_acl;
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    else
+                        ret = STATUS_NO_MEMORY;
+                }
+            }
+            else
+                ret = STATUS_NO_MEMORY;
+        }
+    }
+    else
+        ret = STATUS_NO_MEMORY;
+
+    if (new_sid)
+        RtlFreeHeap(GetProcessHeap(), 0, new_sid);
+
+    if (owner)
+        RtlFreeHeap(GetProcessHeap(), 0, owner);
+
+    if ((!NT_SUCCESS(ret)) && (new_acl))
+        RtlFreeHeap(GetProcessHeap(), 0, new_acl);
+
+    if (token)
+        NtClose(token);
+
+    return ret;
 }
-- 
2.32.0




More information about the wine-devel mailing list