[LSASRV]
authorEric Kohl <eric.kohl@reactos.org>
Mon, 19 Nov 2012 21:33:07 +0000 (21:33 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 19 Nov 2012 21:33:07 +0000 (21:33 +0000)
- Move LsapCreatePolicySd into a separate file.
- Create and set a security descriptor to newly created accounts.

svn path=/trunk/; revision=57737

reactos/dll/win32/lsasrv/CMakeLists.txt
reactos/dll/win32/lsasrv/database.c
reactos/dll/win32/lsasrv/lsarpc.c
reactos/dll/win32/lsasrv/lsasrv.h
reactos/dll/win32/lsasrv/security.c [new file with mode: 0644]

index 28d5533..71b4d0a 100644 (file)
@@ -18,6 +18,7 @@ list(APPEND SOURCE
     lsasrv.c
     policy.c
     privileges.c
+    security.c
     lsasrv.rc
     ${CMAKE_CURRENT_BINARY_DIR}/lsasrv_stubs.c
     ${CMAKE_CURRENT_BINARY_DIR}/lsasrv.def
index a196800..9303636 100644 (file)
@@ -233,260 +233,6 @@ LsapCreateRandomDomainSid(OUT PSID *Sid)
 }
 
 
-static NTSTATUS
-LsapCreatePolicySd(PSECURITY_DESCRIPTOR *PolicySd,
-                   PULONG PolicySdSize)
-{
-    SECURITY_DESCRIPTOR AbsoluteSd;
-    PSECURITY_DESCRIPTOR RelativeSd = NULL;
-    ULONG RelativeSdSize = 0;
-    PSID AnonymousSid = NULL;
-    PSID AdministratorsSid = NULL;
-    PSID EveryoneSid = NULL;
-    PSID LocalServiceSid = NULL;
-    PSID NetworkServiceSid = NULL;
-    PSID LocalSystemSid = NULL;
-    PACL Dacl = NULL;
-    ULONG DaclSize;
-    NTSTATUS Status;
-
-    if (PolicySd == NULL || PolicySdSize == NULL)
-        return STATUS_INVALID_PARAMETER;
-
-    *PolicySd = NULL;
-    *PolicySdSize = 0;
-
-    /* Initialize the SD */
-    Status = RtlCreateSecurityDescriptor(&AbsoluteSd,
-                                         SECURITY_DESCRIPTOR_REVISION);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    Status = RtlAllocateAndInitializeSid(&NtAuthority,
-                                         1,
-                                         SECURITY_ANONYMOUS_LOGON_RID,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         &AnonymousSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAllocateAndInitializeSid(&NtAuthority,
-                                         2,
-                                         SECURITY_BUILTIN_DOMAIN_RID,
-                                         DOMAIN_ALIAS_RID_ADMINS,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         &AdministratorsSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAllocateAndInitializeSid(&WorldSidAuthority,
-                                         1,
-                                         SECURITY_WORLD_RID,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         &EveryoneSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAllocateAndInitializeSid(&NtAuthority,
-                                         1,
-                                         SECURITY_LOCAL_SERVICE_RID,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         &LocalServiceSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAllocateAndInitializeSid(&NtAuthority,
-                                         1,
-                                         SECURITY_NETWORK_SERVICE_RID,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         &NetworkServiceSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAllocateAndInitializeSid(&NtAuthority,
-                                         1,
-                                         SECURITY_LOCAL_SYSTEM_RID,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         &LocalSystemSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    /* Allocate and initialize the DACL */
-    DaclSize = sizeof(ACL) +
-               sizeof(ACCESS_DENIED_ACE) - sizeof(ULONG) + RtlLengthSid(AnonymousSid) +
-               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AdministratorsSid) +
-               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(EveryoneSid) +
-               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AnonymousSid) +
-               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(LocalServiceSid) +
-               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(NetworkServiceSid);
-
-    Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
-                           HEAP_ZERO_MEMORY,
-                           DaclSize);
-    if (Dacl == NULL)
-    {
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto done;
-    }
-
-    Status = RtlCreateAcl(Dacl,
-                          DaclSize,
-                          ACL_REVISION);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAddAccessDeniedAce(Dacl,
-                                   ACL_REVISION,
-                                   POLICY_LOOKUP_NAMES,
-                                   AnonymousSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAddAccessAllowedAce(Dacl,
-                                    ACL_REVISION,
-                                    POLICY_ALL_ACCESS | POLICY_NOTIFICATION,
-                                    AdministratorsSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAddAccessAllowedAce(Dacl,
-                                    ACL_REVISION,
-                                    POLICY_EXECUTE,
-                                    EveryoneSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAddAccessAllowedAce(Dacl,
-                                    ACL_REVISION,
-                                    POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION,
-                                    AnonymousSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAddAccessAllowedAce(Dacl,
-                                    ACL_REVISION,
-                                    POLICY_NOTIFICATION,
-                                    LocalServiceSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAddAccessAllowedAce(Dacl,
-                                    ACL_REVISION,
-                                    POLICY_NOTIFICATION,
-                                    NetworkServiceSid);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd,
-                                          TRUE,
-                                          Dacl,
-                                          FALSE);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlSetGroupSecurityDescriptor(&AbsoluteSd,
-                                           LocalSystemSid,
-                                           FALSE);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd,
-                                           AdministratorsSid,
-                                           FALSE);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
-                                         RelativeSd,
-                                         &RelativeSdSize);
-    if (Status != STATUS_BUFFER_TOO_SMALL)
-        goto done;
-
-    RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(),
-                                 HEAP_ZERO_MEMORY,
-                                 RelativeSdSize);
-    if (RelativeSd == NULL)
-    {
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto done;
-    }
-
-    Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
-                                         RelativeSd,
-                                         &RelativeSdSize);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    *PolicySd = RelativeSd;
-    *PolicySdSize = RelativeSdSize;
-
-done:
-    if (Dacl != NULL)
-        RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
-
-    if (AnonymousSid != NULL)
-        RtlFreeHeap(RtlGetProcessHeap(), 0, AnonymousSid);
-
-    if (AdministratorsSid != NULL)
-        RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid);
-
-    if (EveryoneSid != NULL)
-        RtlFreeHeap(RtlGetProcessHeap(), 0, EveryoneSid);
-
-    if (LocalServiceSid != NULL)
-        RtlFreeHeap(RtlGetProcessHeap(), 0, LocalServiceSid);
-
-    if (NetworkServiceSid != NULL)
-        RtlFreeHeap(RtlGetProcessHeap(), 0, NetworkServiceSid);
-
-    if (LocalSystemSid != NULL)
-        RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid);
-
-    if (!NT_SUCCESS(Status))
-    {
-        if (RelativeSd != NULL)
-            RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd);
-    }
-
-    return Status;
-}
-
-
 static NTSTATUS
 LsapCreateDatabaseObjects(VOID)
 {
index 19f077c..b0b8699 100644 (file)
@@ -513,6 +513,8 @@ NTSTATUS WINAPI LsarCreateAccount(
     PLSA_DB_OBJECT PolicyObject;
     PLSA_DB_OBJECT AccountObject = NULL;
     LPWSTR SidString = NULL;
+    PSECURITY_DESCRIPTOR AccountSd = NULL;
+    ULONG AccountSdSize;
     NTSTATUS Status = STATUS_SUCCESS;
 
     /* Validate the AccountSid */
@@ -539,6 +541,15 @@ NTSTATUS WINAPI LsarCreateAccount(
         goto done;
     }
 
+    /* Create a security descriptor for the account */
+    Status = LsapCreateAccountSd(&AccountSd,
+                                 &AccountSdSize);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapCreateAccountSd returned 0x%08lx\n", Status);
+        return Status;
+    }
+
     /* Create the Account object */
     Status = LsapCreateDbObject(PolicyObject,
                                 L"Accounts",
@@ -557,11 +568,22 @@ NTSTATUS WINAPI LsarCreateAccount(
                                     L"Sid",
                                     (PVOID)AccountSid,
                                     GetLengthSid(AccountSid));
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    /* Set the SecDesc attribute */
+    Status = LsapSetObjectAttribute(AccountObject,
+                                    L"SecDesc",
+                                    AccountSd,
+                                    AccountSdSize);
 
 done:
     if (SidString != NULL)
         LocalFree(SidString);
 
+    if (AccountSd != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, AccountSd);
+
     if (!NT_SUCCESS(Status))
     {
         if (AccountObject != NULL)
index 5f18e5a..3239376 100644 (file)
@@ -227,4 +227,13 @@ LsarpEnumeratePrivileges(DWORD *EnumerationContext,
                          PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer,
                          DWORD PreferedMaximumLength);
 
+/* security.c */
+NTSTATUS
+LsapCreatePolicySd(PSECURITY_DESCRIPTOR *PolicySd,
+                   PULONG PolicySdSize);
+
+NTSTATUS
+LsapCreateAccountSd(PSECURITY_DESCRIPTOR *AccountSd,
+                    PULONG AccountSdSize);
+
 /* EOF */
diff --git a/reactos/dll/win32/lsasrv/security.c b/reactos/dll/win32/lsasrv/security.c
new file mode 100644 (file)
index 0000000..b8173b5
--- /dev/null
@@ -0,0 +1,439 @@
+/*
+ * PROJECT:     Local Security Authority Server DLL
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        dll/win32/lsasrv/security.c
+ * PURPOSE:     LSA object security functions
+ * COPYRIGHT:   Copyright 2012 Eric Kohl
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include "lsasrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
+
+
+/* FUNCTIONS ***************************************************************/
+
+NTSTATUS
+LsapCreatePolicySd(PSECURITY_DESCRIPTOR *PolicySd,
+                   PULONG PolicySdSize)
+{
+    SECURITY_DESCRIPTOR AbsoluteSd;
+    PSECURITY_DESCRIPTOR RelativeSd = NULL;
+    ULONG RelativeSdSize = 0;
+    PSID AnonymousSid = NULL;
+    PSID AdministratorsSid = NULL;
+    PSID EveryoneSid = NULL;
+    PSID LocalServiceSid = NULL;
+    PSID NetworkServiceSid = NULL;
+    PSID LocalSystemSid = NULL;
+    PACL Dacl = NULL;
+    ULONG DaclSize;
+    NTSTATUS Status;
+
+    if (PolicySd == NULL || PolicySdSize == NULL)
+        return STATUS_INVALID_PARAMETER;
+
+    *PolicySd = NULL;
+    *PolicySdSize = 0;
+
+    /* Initialize the SD */
+    Status = RtlCreateSecurityDescriptor(&AbsoluteSd,
+                                         SECURITY_DESCRIPTOR_REVISION);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    Status = RtlAllocateAndInitializeSid(&NtAuthority,
+                                         1,
+                                         SECURITY_ANONYMOUS_LOGON_RID,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         &AnonymousSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAllocateAndInitializeSid(&NtAuthority,
+                                         2,
+                                         SECURITY_BUILTIN_DOMAIN_RID,
+                                         DOMAIN_ALIAS_RID_ADMINS,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         &AdministratorsSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAllocateAndInitializeSid(&WorldSidAuthority,
+                                         1,
+                                         SECURITY_WORLD_RID,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         &EveryoneSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAllocateAndInitializeSid(&NtAuthority,
+                                         1,
+                                         SECURITY_LOCAL_SERVICE_RID,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         &LocalServiceSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAllocateAndInitializeSid(&NtAuthority,
+                                         1,
+                                         SECURITY_NETWORK_SERVICE_RID,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         &NetworkServiceSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAllocateAndInitializeSid(&NtAuthority,
+                                         1,
+                                         SECURITY_LOCAL_SYSTEM_RID,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         &LocalSystemSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    /* Allocate and initialize the DACL */
+    DaclSize = sizeof(ACL) +
+               sizeof(ACCESS_DENIED_ACE) - sizeof(ULONG) + RtlLengthSid(AnonymousSid) +
+               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AdministratorsSid) +
+               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(EveryoneSid) +
+               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AnonymousSid) +
+               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(LocalServiceSid) +
+               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(NetworkServiceSid);
+
+    Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
+                           HEAP_ZERO_MEMORY,
+                           DaclSize);
+    if (Dacl == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    Status = RtlCreateAcl(Dacl,
+                          DaclSize,
+                          ACL_REVISION);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAddAccessDeniedAce(Dacl,
+                                   ACL_REVISION,
+                                   POLICY_LOOKUP_NAMES,
+                                   AnonymousSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAddAccessAllowedAce(Dacl,
+                                    ACL_REVISION,
+                                    POLICY_ALL_ACCESS | POLICY_NOTIFICATION,
+                                    AdministratorsSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAddAccessAllowedAce(Dacl,
+                                    ACL_REVISION,
+                                    POLICY_EXECUTE,
+                                    EveryoneSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAddAccessAllowedAce(Dacl,
+                                    ACL_REVISION,
+                                    POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION,
+                                    AnonymousSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAddAccessAllowedAce(Dacl,
+                                    ACL_REVISION,
+                                    POLICY_NOTIFICATION,
+                                    LocalServiceSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAddAccessAllowedAce(Dacl,
+                                    ACL_REVISION,
+                                    POLICY_NOTIFICATION,
+                                    NetworkServiceSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd,
+                                          TRUE,
+                                          Dacl,
+                                          FALSE);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlSetGroupSecurityDescriptor(&AbsoluteSd,
+                                           LocalSystemSid,
+                                           FALSE);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd,
+                                           AdministratorsSid,
+                                           FALSE);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
+                                         RelativeSd,
+                                         &RelativeSdSize);
+    if (Status != STATUS_BUFFER_TOO_SMALL)
+        goto done;
+
+    RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(),
+                                 HEAP_ZERO_MEMORY,
+                                 RelativeSdSize);
+    if (RelativeSd == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
+                                         RelativeSd,
+                                         &RelativeSdSize);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    *PolicySd = RelativeSd;
+    *PolicySdSize = RelativeSdSize;
+
+done:
+    if (Dacl != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
+
+    if (AnonymousSid != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, AnonymousSid);
+
+    if (AdministratorsSid != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid);
+
+    if (EveryoneSid != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, EveryoneSid);
+
+    if (LocalServiceSid != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, LocalServiceSid);
+
+    if (NetworkServiceSid != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, NetworkServiceSid);
+
+    if (LocalSystemSid != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (RelativeSd != NULL)
+            RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd);
+    }
+
+    return Status;
+}
+
+
+NTSTATUS
+LsapCreateAccountSd(PSECURITY_DESCRIPTOR *AccountSd,
+                    PULONG AccountSdSize)
+{
+    SECURITY_DESCRIPTOR AbsoluteSd;
+    PSECURITY_DESCRIPTOR RelativeSd = NULL;
+    ULONG RelativeSdSize = 0;
+    PSID AdministratorsSid = NULL;
+    PSID EveryoneSid = NULL;
+    PSID LocalSystemSid = NULL;
+    PACL Dacl = NULL;
+    ULONG DaclSize;
+    NTSTATUS Status;
+
+    if (AccountSd == NULL || AccountSdSize == NULL)
+        return STATUS_INVALID_PARAMETER;
+
+    *AccountSd = NULL;
+    *AccountSdSize = 0;
+
+    /* Initialize the SD */
+    Status = RtlCreateSecurityDescriptor(&AbsoluteSd,
+                                         SECURITY_DESCRIPTOR_REVISION);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    Status = RtlAllocateAndInitializeSid(&NtAuthority,
+                                         2,
+                                         SECURITY_BUILTIN_DOMAIN_RID,
+                                         DOMAIN_ALIAS_RID_ADMINS,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         &AdministratorsSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAllocateAndInitializeSid(&WorldSidAuthority,
+                                         1,
+                                         SECURITY_WORLD_RID,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         &EveryoneSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAllocateAndInitializeSid(&NtAuthority,
+                                         1,
+                                         SECURITY_LOCAL_SYSTEM_RID,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         &LocalSystemSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    /* Allocate and initialize the DACL */
+    DaclSize = sizeof(ACL) +
+               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AdministratorsSid) +
+               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(EveryoneSid);
+
+    Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
+                           HEAP_ZERO_MEMORY,
+                           DaclSize);
+    if (Dacl == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    Status = RtlCreateAcl(Dacl,
+                          DaclSize,
+                          ACL_REVISION);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAddAccessAllowedAce(Dacl,
+                                    ACL_REVISION,
+                                    ACCOUNT_ALL_ACCESS,
+                                    AdministratorsSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAddAccessAllowedAce(Dacl,
+                                    ACL_REVISION,
+                                    ACCOUNT_EXECUTE,
+                                    EveryoneSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd,
+                                          TRUE,
+                                          Dacl,
+                                          FALSE);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlSetGroupSecurityDescriptor(&AbsoluteSd,
+                                           LocalSystemSid,
+                                           FALSE);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd,
+                                           AdministratorsSid,
+                                           FALSE);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
+                                         RelativeSd,
+                                         &RelativeSdSize);
+    if (Status != STATUS_BUFFER_TOO_SMALL)
+        goto done;
+
+    RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(),
+                                 HEAP_ZERO_MEMORY,
+                                 RelativeSdSize);
+    if (RelativeSd == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
+                                         RelativeSd,
+                                         &RelativeSdSize);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    *AccountSd = RelativeSd;
+    *AccountSdSize = RelativeSdSize;
+
+done:
+    if (Dacl != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
+
+    if (AdministratorsSid != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid);
+
+    if (EveryoneSid != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, EveryoneSid);
+
+    if (LocalSystemSid != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (RelativeSd != NULL)
+            RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd);
+    }
+
+    return Status;
+}
+
+/* EOF */