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 ***************************************************************/
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),
GUID DnsDomainGuid;
PLSA_DB_OBJECT PolicyObject = NULL;
PSID AccountDomainSid = NULL;
+ PSECURITY_DESCRIPTOR PolicySd = NULL;
+ ULONG PolicySdSize = 0;
ULONG AuditEventsCount;
ULONG AuditEventsSize;
ULONG i;
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;
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;
&DnsDomainGuid,
sizeof(GUID));
+ /* Set the Sceurity Descriptor */
+ LsapSetObjectAttribute(PolicyObject,
+ L"SecDesc",
+ PolicySd,
+ PolicySdSize);
+
done:
if (AuditEventsInfo != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, AuditEventsInfo);
if (AccountDomainSid != NULL)
RtlFreeSid(AccountDomainSid);
+ if (PolicySd != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, PolicySd);
+
return Status;
}
}
+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)
{
}
}
+ 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;
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;
NewObject->Access = DesiredAccess;
NewObject->KeyHandle = ObjectKeyHandle;
NewObject->ParentObject = ParentObject;
+ NewObject->Trusted = Trusted;
if (ParentObject != NULL)
ParentObject->RefCount++;
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;
NewObject->Access = DesiredAccess;
NewObject->KeyHandle = ObjectKeyHandle;
NewObject->ParentObject = ParentObject;
+ NewObject->Trusted = Trusted;
if (ParentObject != NULL)
ParentObject->RefCount++;
}
+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,
return Status;
}
+
+NTSTATUS
+LsapDeleteObjectAttribute(PLSA_DB_OBJECT DbObject,
+ LPWSTR AttributeName)
+{
+ return LsapRegDeleteSubKey(DbObject->KeyHandle,
+ AttributeName);
+}
+
/* EOF */