[LSASRV]
[reactos.git] / reactos / dll / win32 / lsasrv / database.c
index 6251a0e..c74604d 100644 (file)
@@ -17,6 +17,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
 
 static HANDLE SecurityKeyHandle = NULL;
 
+SID_IDENTIFIER_AUTHORITY NullSidAuthority    = {SECURITY_NULL_SID_AUTHORITY};
+SID_IDENTIFIER_AUTHORITY WorldSidAuthority   = {SECURITY_WORLD_SID_AUTHORITY};
+SID_IDENTIFIER_AUTHORITY LocalSidAuthority   = {SECURITY_LOCAL_SID_AUTHORITY};
+SID_IDENTIFIER_AUTHORITY CreatorSidAuthority = {SECURITY_CREATOR_SID_AUTHORITY};
+SID_IDENTIFIER_AUTHORITY NtAuthority         = {SECURITY_NT_AUTHORITY};
+
+PSID BuiltinDomainSid = NULL;
+PSID AccountDomainSid = NULL;
+UNICODE_STRING BuiltinDomainName = {0, 0, NULL};
+UNICODE_STRING AccountDomainName = {0, 0, NULL};
+
 
 /* FUNCTIONS ***************************************************************/
 
@@ -202,14 +213,13 @@ Done:
 static NTSTATUS
 LsapCreateRandomDomainSid(OUT PSID *Sid)
 {
-    SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
     LARGE_INTEGER SystemTime;
     PULONG Seed;
 
     NtQuerySystemTime(&SystemTime);
     Seed = &SystemTime.u.LowPart;
 
-    return RtlAllocateAndInitializeSid(&SystemAuthority,
+    return RtlAllocateAndInitializeSid(&NtAuthority,
                                        4,
                                        SECURITY_NT_NON_UNIQUE,
                                        RtlUniform(Seed),
@@ -234,6 +244,8 @@ LsapCreateDatabaseObjects(VOID)
     GUID DnsDomainGuid;
     PLSA_DB_OBJECT PolicyObject = NULL;
     PSID AccountDomainSid = NULL;
+    PSECURITY_DESCRIPTOR PolicySd = NULL;
+    ULONG PolicySdSize = 0;
     ULONG AuditEventsCount;
     ULONG AuditEventsSize;
     ULONG i;
@@ -259,7 +271,7 @@ LsapCreateDatabaseObjects(VOID)
     AuditEventsCount = AuditCategoryAccountLogon - AuditCategorySystem + 1;
     AuditEventsSize = sizeof(LSAP_POLICY_AUDIT_EVENTS_DATA) + AuditEventsCount * sizeof(DWORD);
     AuditEventsInfo = RtlAllocateHeap(RtlGetProcessHeap(),
-                                      0,
+                                      HEAP_ZERO_MEMORY,
                                       AuditEventsSize);
     if (AuditEventsInfo == NULL)
         return STATUS_INSUFFICIENT_RESOURCES;
@@ -281,12 +293,18 @@ LsapCreateDatabaseObjects(VOID)
     if (!NT_SUCCESS(Status))
         goto done;
 
+    Status = LsapCreatePolicySd(&PolicySd,
+                                &PolicySdSize);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
     /* Open the 'Policy' object */
     Status = LsapOpenDbObject(NULL,
                               NULL,
                               L"Policy",
                               LsaDbPolicyObject,
                               0,
+                              TRUE,
                               &PolicyObject);
     if (!NT_SUCCESS(Status))
         goto done;
@@ -359,6 +377,12 @@ LsapCreateDatabaseObjects(VOID)
                            &DnsDomainGuid,
                            sizeof(GUID));
 
+    /* Set the Sceurity Descriptor */
+    LsapSetObjectAttribute(PolicyObject,
+                           L"SecDesc",
+                           PolicySd,
+                           PolicySdSize);
+
 done:
     if (AuditEventsInfo != NULL)
         RtlFreeHeap(RtlGetProcessHeap(), 0, AuditEventsInfo);
@@ -369,6 +393,9 @@ done:
     if (AccountDomainSid != NULL)
         RtlFreeSid(AccountDomainSid);
 
+    if (PolicySd != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, PolicySd);
+
     return Status;
 }
 
@@ -380,6 +407,138 @@ LsapUpdateDatabase(VOID)
 }
 
 
+static NTSTATUS
+LsapGetDomainInfo(VOID)
+{
+    PLSA_DB_OBJECT PolicyObject = NULL;
+    PUNICODE_STRING DomainName = NULL;
+    ULONG AttributeSize;
+    LPWSTR SidString = NULL;
+    NTSTATUS Status;
+
+    /* Get the built-in domain SID and name */
+    Status = RtlAllocateAndInitializeSid(&NtAuthority,
+                                         1,
+                                         SECURITY_BUILTIN_DOMAIN_RID,
+                                         0, 0, 0, 0, 0, 0, 0,
+                                         &BuiltinDomainSid);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    /**/
+    RtlInitUnicodeString(&BuiltinDomainName,
+                         L"BUILTIN");
+
+    /* Open the 'Policy' object */
+    Status = LsapOpenDbObject(NULL,
+                              NULL,
+                              L"Policy",
+                              LsaDbPolicyObject,
+                              0,
+                              TRUE,
+                              &PolicyObject);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    /* Get the account domain SID */
+    AttributeSize = 0;
+    Status = LsapGetObjectAttribute(PolicyObject,
+                                    L"PolAcDmS",
+                                    NULL,
+                                    &AttributeSize);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    if (AttributeSize > 0)
+    {
+        AccountDomainSid = RtlAllocateHeap(RtlGetProcessHeap(),
+                                           HEAP_ZERO_MEMORY,
+                                           AttributeSize);
+        if (AccountDomainSid == NULL)
+        {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto done;
+        }
+
+        Status = LsapGetObjectAttribute(PolicyObject,
+                                        L"PolAcDmS",
+                                        AccountDomainSid,
+                                        &AttributeSize);
+        if (!NT_SUCCESS(Status))
+            goto done;
+    }
+
+    /* Get the account domain name */
+    AttributeSize = 0;
+    Status = LsapGetObjectAttribute(PolicyObject,
+                                    L"PolAcDmN",
+                                    NULL,
+                                    &AttributeSize);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    if (AttributeSize > 0)
+    {
+        DomainName = RtlAllocateHeap(RtlGetProcessHeap(),
+                                     HEAP_ZERO_MEMORY,
+                                     AttributeSize);
+        if (DomainName == NULL)
+        {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto done;
+        }
+
+        Status = LsapGetObjectAttribute(PolicyObject,
+                                        L"PolAcDmN",
+                                        DomainName,
+                                        &AttributeSize);
+        if (!NT_SUCCESS(Status))
+            goto done;
+
+        DomainName->Buffer = (LPWSTR)((ULONG_PTR)DomainName + (ULONG_PTR)DomainName->Buffer);
+
+        AccountDomainName.Length = DomainName->Length;
+        AccountDomainName.MaximumLength = DomainName->Length + sizeof(WCHAR);
+        AccountDomainName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                                   HEAP_ZERO_MEMORY,
+                                                   AccountDomainName.MaximumLength);
+        if (AccountDomainName.Buffer == NULL)
+        {
+            ERR("Failed to allocate the account domain name buffer\n");
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto done;
+        }
+
+        RtlCopyMemory(AccountDomainName.Buffer,
+                      DomainName->Buffer,
+                      DomainName->Length);
+    }
+
+    ConvertSidToStringSidW(BuiltinDomainSid, &SidString);
+    TRACE("Builtin Domain SID: %S\n", SidString);
+    LocalFree(SidString);
+    SidString = NULL;
+
+    TRACE("Builtin Domain Name: %wZ\n", &BuiltinDomainName);
+
+    ConvertSidToStringSidW(AccountDomainSid, &SidString);
+    TRACE("Account Domain SID: %S\n", SidString);
+    LocalFree(SidString);
+    SidString = NULL;
+
+    TRACE("Account Domain Name: %wZ\n", &AccountDomainName);
+
+done:
+    if (DomainName != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, DomainName);
+
+    if (PolicyObject != NULL)
+        LsapCloseDbObject(PolicyObject);
+
+    return Status;
+}
+
+
 NTSTATUS
 LsapInitDatabase(VOID)
 {
@@ -420,6 +579,13 @@ LsapInitDatabase(VOID)
         }
     }
 
+    Status = LsapGetDomainInfo();
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("Failed to get the domain information (Status: 0x%08lx)\n", Status);
+        return Status;
+    }
+
     TRACE("LsapInitDatabase() done\n");
 
     return STATUS_SUCCESS;
@@ -432,6 +598,7 @@ LsapCreateDbObject(IN PLSA_DB_OBJECT ParentObject,
                    IN LPWSTR ObjectName,
                    IN LSA_DB_OBJECT_TYPE ObjectType,
                    IN ACCESS_MASK DesiredAccess,
+                   IN BOOLEAN Trusted,
                    OUT PLSA_DB_OBJECT *DbObject)
 {
     PLSA_DB_OBJECT NewObject;
@@ -534,6 +701,7 @@ LsapCreateDbObject(IN PLSA_DB_OBJECT ParentObject,
     NewObject->Access = DesiredAccess;
     NewObject->KeyHandle = ObjectKeyHandle;
     NewObject->ParentObject = ParentObject;
+    NewObject->Trusted = Trusted;
 
     if (ParentObject != NULL)
         ParentObject->RefCount++;
@@ -550,6 +718,7 @@ LsapOpenDbObject(IN PLSA_DB_OBJECT ParentObject,
                  IN LPWSTR ObjectName,
                  IN LSA_DB_OBJECT_TYPE ObjectType,
                  IN ACCESS_MASK DesiredAccess,
+                 IN BOOLEAN Trusted,
                  OUT PLSA_DB_OBJECT *DbObject)
 {
     PLSA_DB_OBJECT NewObject;
@@ -645,6 +814,7 @@ LsapOpenDbObject(IN PLSA_DB_OBJECT ParentObject,
     NewObject->Access = DesiredAccess;
     NewObject->KeyHandle = ObjectKeyHandle;
     NewObject->ParentObject = ParentObject;
+    NewObject->Trusted = Trusted;
 
     if (ParentObject != NULL)
         ParentObject->RefCount++;
@@ -731,6 +901,66 @@ LsapCloseDbObject(PLSA_DB_OBJECT DbObject)
 }
 
 
+NTSTATUS
+LsapDeleteDbObject(IN PLSA_DB_OBJECT DbObject)
+{
+    PLSA_DB_OBJECT ParentObject = NULL;
+    WCHAR KeyName[64];
+    ULONG Index;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    DbObject->RefCount--;
+
+    if (DbObject->RefCount > 0)
+        return STATUS_SUCCESS;
+
+    if (DbObject->KeyHandle != NULL)
+    {
+        Index = 0;
+
+        while (TRUE)
+        {
+            Status = LsapRegEnumerateSubKey(DbObject->KeyHandle,
+                                            Index,
+                                            64 * sizeof(WCHAR),
+                                            KeyName);
+            if (!NT_SUCCESS(Status))
+                break;
+
+            TRACE("Index: %lu\n", Index);
+            TRACE("Key name: %S\n", KeyName);
+
+            Status = LsapRegDeleteSubKey(DbObject->KeyHandle,
+                                         KeyName);
+            if (!NT_SUCCESS(Status))
+                break;
+        }
+
+        if (Status == STATUS_NO_MORE_ENTRIES)
+            Status = STATUS_SUCCESS;
+
+        LsapRegDeleteKey(DbObject->KeyHandle);
+
+        NtClose(DbObject->KeyHandle);
+    }
+
+    if (DbObject->ParentObject != NULL)
+        ParentObject = DbObject->ParentObject;
+
+    RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject);
+
+    if (ParentObject != NULL)
+    {
+        ParentObject->RefCount--;
+
+        if (ParentObject->RefCount == 0)
+            Status = LsapCloseDbObject(ParentObject);
+    }
+
+    return Status;
+}
+
+
 NTSTATUS
 LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject,
                        LPWSTR AttributeName,
@@ -844,5 +1074,14 @@ Done:
     return Status;
 }
 
+
+NTSTATUS
+LsapDeleteObjectAttribute(PLSA_DB_OBJECT DbObject,
+                          LPWSTR AttributeName)
+{
+    return LsapRegDeleteSubKey(DbObject->KeyHandle,
+                               AttributeName);
+}
+
 /* EOF */