2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/lsasrv/database.c
5 * PURPOSE: LSA object database
6 * COPYRIGHT: Copyright 2011 Eric Kohl
11 /* GLOBALS *****************************************************************/
13 static HANDLE SecurityKeyHandle
= NULL
;
15 SID_IDENTIFIER_AUTHORITY NullSidAuthority
= {SECURITY_NULL_SID_AUTHORITY
};
16 SID_IDENTIFIER_AUTHORITY WorldSidAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
17 SID_IDENTIFIER_AUTHORITY LocalSidAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
18 SID_IDENTIFIER_AUTHORITY CreatorSidAuthority
= {SECURITY_CREATOR_SID_AUTHORITY
};
19 SID_IDENTIFIER_AUTHORITY NtAuthority
= {SECURITY_NT_AUTHORITY
};
21 PSID BuiltinDomainSid
= NULL
;
22 PSID AccountDomainSid
= NULL
;
23 UNICODE_STRING BuiltinDomainName
= {0, 0, NULL
};
24 UNICODE_STRING AccountDomainName
= {0, 0, NULL
};
27 /* FUNCTIONS ***************************************************************/
30 LsapOpenServiceKey(VOID
)
32 OBJECT_ATTRIBUTES ObjectAttributes
;
33 UNICODE_STRING KeyName
;
36 RtlInitUnicodeString(&KeyName
,
37 L
"\\Registry\\Machine\\SECURITY");
39 InitializeObjectAttributes(&ObjectAttributes
,
45 Status
= RtlpNtOpenKey(&SecurityKeyHandle
,
46 KEY_READ
| KEY_CREATE_SUB_KEY
| KEY_ENUMERATE_SUB_KEYS
,
55 LsapIsDatabaseInstalled(VOID
)
57 OBJECT_ATTRIBUTES ObjectAttributes
;
58 UNICODE_STRING KeyName
;
62 RtlInitUnicodeString(&KeyName
,
65 InitializeObjectAttributes(&ObjectAttributes
,
71 Status
= RtlpNtOpenKey(&KeyHandle
,
75 if (!NT_SUCCESS(Status
))
85 LsapCreateDatabaseKeys(VOID
)
87 OBJECT_ATTRIBUTES ObjectAttributes
;
88 UNICODE_STRING KeyName
;
89 HANDLE PolicyKeyHandle
= NULL
;
90 HANDLE AccountsKeyHandle
= NULL
;
91 HANDLE DomainsKeyHandle
= NULL
;
92 HANDLE SecretsKeyHandle
= NULL
;
93 NTSTATUS Status
= STATUS_SUCCESS
;
95 TRACE("LsapInstallDatabase()\n");
97 /* Create the 'Policy' key */
98 RtlInitUnicodeString(&KeyName
,
101 InitializeObjectAttributes(&ObjectAttributes
,
103 OBJ_CASE_INSENSITIVE
,
107 Status
= NtCreateKey(&PolicyKeyHandle
,
114 if (!NT_SUCCESS(Status
))
116 ERR("Failed to create the 'Policy' key (Status: 0x%08lx)\n", Status
);
120 /* Create the 'Accounts' key */
121 RtlInitUnicodeString(&KeyName
,
124 InitializeObjectAttributes(&ObjectAttributes
,
126 OBJ_CASE_INSENSITIVE
,
130 Status
= NtCreateKey(&AccountsKeyHandle
,
137 if (!NT_SUCCESS(Status
))
139 ERR("Failed to create the 'Accounts' key (Status: 0x%08lx)\n", Status
);
143 /* Create the 'Domains' key */
144 RtlInitUnicodeString(&KeyName
,
147 InitializeObjectAttributes(&ObjectAttributes
,
149 OBJ_CASE_INSENSITIVE
,
153 Status
= NtCreateKey(&DomainsKeyHandle
,
160 if (!NT_SUCCESS(Status
))
162 ERR("Failed to create the 'Domains' key (Status: 0x%08lx)\n", Status
);
166 /* Create the 'Secrets' key */
167 RtlInitUnicodeString(&KeyName
,
170 InitializeObjectAttributes(&ObjectAttributes
,
172 OBJ_CASE_INSENSITIVE
,
176 Status
= NtCreateKey(&SecretsKeyHandle
,
183 if (!NT_SUCCESS(Status
))
185 ERR("Failed to create the 'Secrets' key (Status: 0x%08lx)\n", Status
);
190 if (SecretsKeyHandle
!= NULL
)
191 NtClose(SecretsKeyHandle
);
193 if (DomainsKeyHandle
!= NULL
)
194 NtClose(DomainsKeyHandle
);
196 if (AccountsKeyHandle
!= NULL
)
197 NtClose(AccountsKeyHandle
);
199 if (PolicyKeyHandle
!= NULL
)
200 NtClose(PolicyKeyHandle
);
202 TRACE("LsapInstallDatabase() done (Status: 0x%08lx)\n", Status
);
209 LsapCreateRandomDomainSid(OUT PSID
*Sid
)
211 LARGE_INTEGER SystemTime
;
214 NtQuerySystemTime(&SystemTime
);
215 Seed
= &SystemTime
.u
.LowPart
;
217 return RtlAllocateAndInitializeSid(&NtAuthority
,
219 SECURITY_NT_NON_UNIQUE
,
232 LsapCreateDatabaseObjects(VOID
)
234 PLSAP_POLICY_AUDIT_EVENTS_DATA AuditEventsInfo
= NULL
;
235 POLICY_DEFAULT_QUOTA_INFO QuotaInfo
;
236 POLICY_MODIFICATION_INFO ModificationInfo
;
237 POLICY_AUDIT_FULL_QUERY_INFO AuditFullInfo
= {FALSE
, FALSE
};
238 POLICY_AUDIT_LOG_INFO AuditLogInfo
;
240 PLSA_DB_OBJECT PolicyObject
= NULL
;
241 PSID AccountDomainSid
= NULL
;
242 PSECURITY_DESCRIPTOR PolicySd
= NULL
;
243 ULONG PolicySdSize
= 0;
247 /* Initialize the default quota limits */
248 QuotaInfo
.QuotaLimits
.PagedPoolLimit
= 0x2000000;
249 QuotaInfo
.QuotaLimits
.NonPagedPoolLimit
= 0x100000;
250 QuotaInfo
.QuotaLimits
.MinimumWorkingSetSize
= 0x10000;
251 QuotaInfo
.QuotaLimits
.MaximumWorkingSetSize
= 0xF000000;
252 QuotaInfo
.QuotaLimits
.PagefileLimit
= 0;
253 QuotaInfo
.QuotaLimits
.TimeLimit
.QuadPart
= 0;
255 /* Initialize the audit log attribute */
256 AuditLogInfo
.AuditLogPercentFull
= 0;
257 AuditLogInfo
.MaximumLogSize
= 0; // DWORD
258 AuditLogInfo
.AuditRetentionPeriod
.QuadPart
= 0; // LARGE_INTEGER
259 AuditLogInfo
.AuditLogFullShutdownInProgress
= 0; // BYTE
260 AuditLogInfo
.TimeToShutdown
.QuadPart
= 0; // LARGE_INTEGER
261 AuditLogInfo
.NextAuditRecordId
= 0; // DWORD
263 /* Initialize the Audit Events attribute */
264 AuditEventsInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
266 sizeof(LSAP_POLICY_AUDIT_EVENTS_DATA
));
267 if (AuditEventsInfo
== NULL
)
268 return STATUS_INSUFFICIENT_RESOURCES
;
270 AuditEventsInfo
->AuditingMode
= FALSE
;
271 AuditEventsInfo
->MaximumAuditEventCount
= POLICY_AUDIT_EVENT_TYPE_COUNT
;
272 for (i
= 0; i
< POLICY_AUDIT_EVENT_TYPE_COUNT
; i
++)
273 AuditEventsInfo
->AuditEvents
[i
] = 0;
275 /* Initialize the DNS Domain GUID attribute */
276 RtlZeroMemory(&DnsDomainGuid
, sizeof(DnsDomainGuid
));
278 /* Initialize the modification attribute */
279 ModificationInfo
.ModifiedId
.QuadPart
= 0;
280 NtQuerySystemTime(&ModificationInfo
.DatabaseCreationTime
);
282 /* Create a random domain SID */
283 Status
= LsapCreateRandomDomainSid(&AccountDomainSid
);
284 if (!NT_SUCCESS(Status
))
287 Status
= LsapCreatePolicySd(&PolicySd
, &PolicySdSize
);
288 if (!NT_SUCCESS(Status
))
291 /* Open the 'Policy' object */
292 Status
= LsapOpenDbObject(NULL
,
299 if (!NT_SUCCESS(Status
))
302 /* Set the Primary Domain Name attribute */
303 LsapSetObjectAttribute(PolicyObject
,
308 /* Set the Primary Domain SID attribute */
309 LsapSetObjectAttribute(PolicyObject
,
314 /* Set the Account Domain Name attribute */
315 LsapSetObjectAttribute(PolicyObject
,
320 /* Set the Account Domain SID attribute */
321 LsapSetObjectAttribute(PolicyObject
,
324 RtlLengthSid(AccountDomainSid
));
326 /* Set the default quota limits attribute */
327 LsapSetObjectAttribute(PolicyObject
,
332 /* Set the modification attribute */
333 LsapSetObjectAttribute(PolicyObject
,
336 sizeof(ModificationInfo
));
338 /* Set the audit full attribute */
339 LsapSetObjectAttribute(PolicyObject
,
342 sizeof(AuditFullInfo
));
344 /* Set the audit log attribute */
345 LsapSetObjectAttribute(PolicyObject
,
348 sizeof(AuditLogInfo
));
350 /* Set the audit events attribute */
351 LsapSetObjectAttribute(PolicyObject
,
354 sizeof(*AuditEventsInfo
));
356 /* Set the DNS Domain Name attribute */
357 LsapSetObjectAttribute(PolicyObject
,
362 /* Set the DNS Forest Name attribute */
363 LsapSetObjectAttribute(PolicyObject
,
368 /* Set the DNS Domain GUID attribute */
369 LsapSetObjectAttribute(PolicyObject
,
372 sizeof(DnsDomainGuid
));
374 /* Set the Security Descriptor */
375 LsapSetObjectAttribute(PolicyObject
,
381 if (AuditEventsInfo
!= NULL
)
382 RtlFreeHeap(RtlGetProcessHeap(), 0, AuditEventsInfo
);
384 if (PolicyObject
!= NULL
)
385 LsapCloseDbObject(PolicyObject
);
387 if (AccountDomainSid
!= NULL
)
388 RtlFreeSid(AccountDomainSid
);
390 if (PolicySd
!= NULL
)
391 RtlFreeHeap(RtlGetProcessHeap(), 0, PolicySd
);
398 LsapUpdateDatabase(VOID
)
400 return STATUS_SUCCESS
;
405 LsapGetDomainInfo(VOID
)
407 PLSA_DB_OBJECT PolicyObject
= NULL
;
408 PUNICODE_STRING DomainName
= NULL
;
410 LPWSTR SidString
= NULL
;
413 /* Get the built-in domain SID and name */
414 Status
= RtlAllocateAndInitializeSid(&NtAuthority
,
416 SECURITY_BUILTIN_DOMAIN_RID
,
419 if (!NT_SUCCESS(Status
))
423 RtlInitUnicodeString(&BuiltinDomainName
,
426 /* Open the 'Policy' object */
427 Status
= LsapOpenDbObject(NULL
,
434 if (!NT_SUCCESS(Status
))
437 /* Get the account domain SID */
439 Status
= LsapGetObjectAttribute(PolicyObject
,
443 if (!NT_SUCCESS(Status
))
446 if (AttributeSize
> 0)
448 AccountDomainSid
= RtlAllocateHeap(RtlGetProcessHeap(),
451 if (AccountDomainSid
== NULL
)
453 Status
= STATUS_INSUFFICIENT_RESOURCES
;
457 Status
= LsapGetObjectAttribute(PolicyObject
,
461 if (!NT_SUCCESS(Status
))
465 /* Get the account domain name */
467 Status
= LsapGetObjectAttribute(PolicyObject
,
471 if (!NT_SUCCESS(Status
))
474 if (AttributeSize
> 0)
476 DomainName
= RtlAllocateHeap(RtlGetProcessHeap(),
479 if (DomainName
== NULL
)
481 Status
= STATUS_INSUFFICIENT_RESOURCES
;
485 Status
= LsapGetObjectAttribute(PolicyObject
,
489 if (!NT_SUCCESS(Status
))
492 DomainName
->Buffer
= (LPWSTR
)((ULONG_PTR
)DomainName
+ (ULONG_PTR
)DomainName
->Buffer
);
494 AccountDomainName
.Length
= DomainName
->Length
;
495 AccountDomainName
.MaximumLength
= DomainName
->Length
+ sizeof(WCHAR
);
496 AccountDomainName
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
498 AccountDomainName
.MaximumLength
);
499 if (AccountDomainName
.Buffer
== NULL
)
501 ERR("Failed to allocate the account domain name buffer\n");
502 Status
= STATUS_INSUFFICIENT_RESOURCES
;
506 RtlCopyMemory(AccountDomainName
.Buffer
,
511 ConvertSidToStringSidW(BuiltinDomainSid
, &SidString
);
512 TRACE("Builtin Domain SID: %S\n", SidString
);
513 LocalFree(SidString
);
516 TRACE("Builtin Domain Name: %wZ\n", &BuiltinDomainName
);
518 ConvertSidToStringSidW(AccountDomainSid
, &SidString
);
519 TRACE("Account Domain SID: %S\n", SidString
);
520 LocalFree(SidString
);
523 TRACE("Account Domain Name: %wZ\n", &AccountDomainName
);
526 if (DomainName
!= NULL
)
527 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainName
);
529 if (PolicyObject
!= NULL
)
530 LsapCloseDbObject(PolicyObject
);
537 LsapInitDatabase(VOID
)
541 TRACE("LsapInitDatabase()\n");
543 Status
= LsapOpenServiceKey();
544 if (!NT_SUCCESS(Status
))
546 ERR("Failed to open the service key (Status: 0x%08lx)\n", Status
);
550 if (!LsapIsDatabaseInstalled())
552 Status
= LsapCreateDatabaseKeys();
553 if (!NT_SUCCESS(Status
))
555 ERR("Failed to create the LSA database keys (Status: 0x%08lx)\n", Status
);
559 Status
= LsapCreateDatabaseObjects();
560 if (!NT_SUCCESS(Status
))
562 ERR("Failed to create the LSA database objects (Status: 0x%08lx)\n", Status
);
568 Status
= LsapUpdateDatabase();
569 if (!NT_SUCCESS(Status
))
571 ERR("Failed to update the LSA database (Status: 0x%08lx)\n", Status
);
576 Status
= LsapGetDomainInfo();
577 if (!NT_SUCCESS(Status
))
579 ERR("Failed to get the domain information (Status: 0x%08lx)\n", Status
);
583 TRACE("LsapInitDatabase() done\n");
585 return STATUS_SUCCESS
;
590 LsapCreateDbObject(IN PLSA_DB_OBJECT ParentObject
,
591 IN LPWSTR ContainerName
,
592 IN LPWSTR ObjectName
,
593 IN LSA_DB_OBJECT_TYPE ObjectType
,
594 IN ACCESS_MASK DesiredAccess
,
596 OUT PLSA_DB_OBJECT
*DbObject
)
598 PLSA_DB_OBJECT NewObject
;
599 OBJECT_ATTRIBUTES ObjectAttributes
;
600 UNICODE_STRING KeyName
;
601 HANDLE ParentKeyHandle
;
602 HANDLE ContainerKeyHandle
= NULL
;
603 HANDLE ObjectKeyHandle
= NULL
;
606 if (DbObject
== NULL
)
607 return STATUS_INVALID_PARAMETER
;
609 if (ParentObject
== NULL
)
610 ParentKeyHandle
= SecurityKeyHandle
;
612 ParentKeyHandle
= ParentObject
->KeyHandle
;
614 if (ContainerName
!= NULL
)
616 /* Open the container key */
617 RtlInitUnicodeString(&KeyName
,
620 InitializeObjectAttributes(&ObjectAttributes
,
622 OBJ_CASE_INSENSITIVE
,
626 Status
= NtOpenKey(&ContainerKeyHandle
,
629 if (!NT_SUCCESS(Status
))
634 /* Open the object key */
635 RtlInitUnicodeString(&KeyName
,
638 InitializeObjectAttributes(&ObjectAttributes
,
640 OBJ_CASE_INSENSITIVE
,
644 Status
= NtCreateKey(&ObjectKeyHandle
,
652 NtClose(ContainerKeyHandle
);
654 if (!NT_SUCCESS(Status
))
661 RtlInitUnicodeString(&KeyName
,
664 InitializeObjectAttributes(&ObjectAttributes
,
666 OBJ_CASE_INSENSITIVE
,
670 Status
= NtCreateKey(&ObjectKeyHandle
,
677 if (!NT_SUCCESS(Status
))
683 NewObject
= RtlAllocateHeap(RtlGetProcessHeap(),
685 sizeof(LSA_DB_OBJECT
));
686 if (NewObject
== NULL
)
688 NtClose(ObjectKeyHandle
);
689 return STATUS_NO_MEMORY
;
692 NewObject
->Signature
= LSAP_DB_SIGNATURE
;
693 NewObject
->RefCount
= 1;
694 NewObject
->ObjectType
= ObjectType
;
695 NewObject
->Access
= DesiredAccess
;
696 NewObject
->KeyHandle
= ObjectKeyHandle
;
697 NewObject
->ParentObject
= ParentObject
;
698 NewObject
->Trusted
= Trusted
;
700 if (ParentObject
!= NULL
)
701 ParentObject
->RefCount
++;
703 *DbObject
= NewObject
;
705 return STATUS_SUCCESS
;
710 LsapOpenDbObject(IN PLSA_DB_OBJECT ParentObject
,
711 IN LPWSTR ContainerName
,
712 IN LPWSTR ObjectName
,
713 IN LSA_DB_OBJECT_TYPE ObjectType
,
714 IN ACCESS_MASK DesiredAccess
,
716 OUT PLSA_DB_OBJECT
*DbObject
)
718 PLSA_DB_OBJECT NewObject
;
719 OBJECT_ATTRIBUTES ObjectAttributes
;
720 UNICODE_STRING KeyName
;
721 HANDLE ParentKeyHandle
;
722 HANDLE ContainerKeyHandle
= NULL
;
723 HANDLE ObjectKeyHandle
= NULL
;
726 if (DbObject
== NULL
)
727 return STATUS_INVALID_PARAMETER
;
729 if (ParentObject
== NULL
)
730 ParentKeyHandle
= SecurityKeyHandle
;
732 ParentKeyHandle
= ParentObject
->KeyHandle
;
734 if (ContainerName
!= NULL
)
736 /* Open the container key */
737 RtlInitUnicodeString(&KeyName
,
740 InitializeObjectAttributes(&ObjectAttributes
,
742 OBJ_CASE_INSENSITIVE
,
746 Status
= NtOpenKey(&ContainerKeyHandle
,
749 if (!NT_SUCCESS(Status
))
754 /* Open the object key */
755 RtlInitUnicodeString(&KeyName
,
758 InitializeObjectAttributes(&ObjectAttributes
,
760 OBJ_CASE_INSENSITIVE
,
764 Status
= NtOpenKey(&ObjectKeyHandle
,
768 NtClose(ContainerKeyHandle
);
770 if (!NT_SUCCESS(Status
))
777 /* Open the object key */
778 RtlInitUnicodeString(&KeyName
,
781 InitializeObjectAttributes(&ObjectAttributes
,
783 OBJ_CASE_INSENSITIVE
,
787 Status
= NtOpenKey(&ObjectKeyHandle
,
790 if (!NT_SUCCESS(Status
))
796 NewObject
= RtlAllocateHeap(RtlGetProcessHeap(),
798 sizeof(LSA_DB_OBJECT
));
799 if (NewObject
== NULL
)
801 NtClose(ObjectKeyHandle
);
802 return STATUS_NO_MEMORY
;
805 NewObject
->Signature
= LSAP_DB_SIGNATURE
;
806 NewObject
->RefCount
= 1;
807 NewObject
->ObjectType
= ObjectType
;
808 NewObject
->Access
= DesiredAccess
;
809 NewObject
->KeyHandle
= ObjectKeyHandle
;
810 NewObject
->ParentObject
= ParentObject
;
811 NewObject
->Trusted
= Trusted
;
813 if (ParentObject
!= NULL
)
814 ParentObject
->RefCount
++;
816 *DbObject
= NewObject
;
818 return STATUS_SUCCESS
;
823 LsapValidateDbObject(LSAPR_HANDLE Handle
,
824 LSA_DB_OBJECT_TYPE ObjectType
,
825 ACCESS_MASK DesiredAccess
,
826 PLSA_DB_OBJECT
*DbObject
)
828 PLSA_DB_OBJECT LocalObject
= (PLSA_DB_OBJECT
)Handle
;
829 BOOLEAN bValid
= FALSE
;
833 if (LocalObject
->Signature
== LSAP_DB_SIGNATURE
)
835 if ((ObjectType
== LsaDbIgnoreObject
) ||
836 (LocalObject
->ObjectType
== ObjectType
))
840 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
847 return STATUS_INVALID_HANDLE
;
849 if (DesiredAccess
!= 0)
851 /* Check for granted access rights */
852 if ((LocalObject
->Access
& DesiredAccess
) != DesiredAccess
)
854 ERR("LsapValidateDbObject access check failed %08lx %08lx\n",
855 LocalObject
->Access
, DesiredAccess
);
856 return STATUS_ACCESS_DENIED
;
860 if (DbObject
!= NULL
)
861 *DbObject
= LocalObject
;
863 return STATUS_SUCCESS
;
868 LsapCloseDbObject(PLSA_DB_OBJECT DbObject
)
870 PLSA_DB_OBJECT ParentObject
= NULL
;
871 NTSTATUS Status
= STATUS_SUCCESS
;
873 DbObject
->RefCount
--;
875 if (DbObject
->RefCount
> 0)
876 return STATUS_SUCCESS
;
878 if (DbObject
->KeyHandle
!= NULL
)
879 NtClose(DbObject
->KeyHandle
);
881 if (DbObject
->ParentObject
!= NULL
)
882 ParentObject
= DbObject
->ParentObject
;
884 RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject
);
886 if (ParentObject
!= NULL
)
888 ParentObject
->RefCount
--;
890 if (ParentObject
->RefCount
== 0)
891 Status
= LsapCloseDbObject(ParentObject
);
899 LsapDeleteDbObject(IN PLSA_DB_OBJECT DbObject
)
901 PLSA_DB_OBJECT ParentObject
= NULL
;
904 NTSTATUS Status
= STATUS_SUCCESS
;
906 DbObject
->RefCount
--;
908 if (DbObject
->RefCount
> 0)
909 return STATUS_SUCCESS
;
911 if (DbObject
->KeyHandle
!= NULL
)
917 Status
= LsapRegEnumerateSubKey(DbObject
->KeyHandle
,
921 if (!NT_SUCCESS(Status
))
924 TRACE("Index: %lu\n", Index
);
925 TRACE("Key name: %S\n", KeyName
);
927 Status
= LsapRegDeleteSubKey(DbObject
->KeyHandle
,
929 if (!NT_SUCCESS(Status
))
933 if (Status
== STATUS_NO_MORE_ENTRIES
)
934 Status
= STATUS_SUCCESS
;
936 LsapRegDeleteKey(DbObject
->KeyHandle
);
938 NtClose(DbObject
->KeyHandle
);
941 if (DbObject
->ParentObject
!= NULL
)
942 ParentObject
= DbObject
->ParentObject
;
944 RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject
);
946 if (ParentObject
!= NULL
)
948 ParentObject
->RefCount
--;
950 if (ParentObject
->RefCount
== 0)
951 Status
= LsapCloseDbObject(ParentObject
);
959 LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject
,
960 LPWSTR AttributeName
,
961 LPVOID AttributeData
,
964 OBJECT_ATTRIBUTES ObjectAttributes
;
965 UNICODE_STRING KeyName
;
969 RtlInitUnicodeString(&KeyName
,
972 InitializeObjectAttributes(&ObjectAttributes
,
974 OBJ_CASE_INSENSITIVE
,
978 Status
= NtCreateKey(&AttributeKey
,
983 REG_OPTION_NON_VOLATILE
,
985 if (!NT_SUCCESS(Status
))
987 ERR("NtCreateKey failed for '%S' with status 0x%lx\n",
988 AttributeName
, Status
);
992 Status
= RtlpNtSetValueKey(AttributeKey
,
997 NtClose(AttributeKey
);
999 if (!NT_SUCCESS(Status
))
1001 ERR("RtlpNtSetValueKey failed for '%S' with status 0x%lx\n",
1002 AttributeName
, Status
);
1010 LsapGetObjectAttribute(PLSA_DB_OBJECT DbObject
,
1011 LPWSTR AttributeName
,
1012 LPVOID AttributeData
,
1013 PULONG AttributeSize
)
1015 OBJECT_ATTRIBUTES ObjectAttributes
;
1016 UNICODE_STRING KeyName
;
1017 HANDLE AttributeKey
;
1021 RtlInitUnicodeString(&KeyName
,
1024 InitializeObjectAttributes(&ObjectAttributes
,
1026 OBJ_CASE_INSENSITIVE
,
1027 DbObject
->KeyHandle
,
1030 Status
= NtOpenKey(&AttributeKey
,
1033 if (!NT_SUCCESS(Status
))
1038 ValueSize
= *AttributeSize
;
1039 Status
= RtlpNtQueryValueKey(AttributeKey
,
1044 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
1049 if (AttributeData
== NULL
|| *AttributeSize
== 0)
1051 *AttributeSize
= ValueSize
;
1052 Status
= STATUS_SUCCESS
;
1055 else if (*AttributeSize
< ValueSize
)
1057 *AttributeSize
= ValueSize
;
1058 Status
= STATUS_BUFFER_OVERFLOW
;
1062 Status
= RtlpNtQueryValueKey(AttributeKey
,
1067 if (NT_SUCCESS(Status
))
1069 *AttributeSize
= ValueSize
;
1073 NtClose(AttributeKey
);
1080 LsapDeleteObjectAttribute(PLSA_DB_OBJECT DbObject
,
1081 LPWSTR AttributeName
)
1083 return LsapRegDeleteSubKey(DbObject
->KeyHandle
,