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
9 /* INCLUDES ****************************************************************/
13 WINE_DEFAULT_DEBUG_CHANNEL(lsasrv
);
16 /* GLOBALS *****************************************************************/
18 static HANDLE SecurityKeyHandle
= NULL
;
21 /* FUNCTIONS ***************************************************************/
24 LsapOpenServiceKey(VOID
)
26 OBJECT_ATTRIBUTES ObjectAttributes
;
27 UNICODE_STRING KeyName
;
30 RtlInitUnicodeString(&KeyName
,
31 L
"\\Registry\\Machine\\SECURITY");
33 InitializeObjectAttributes(&ObjectAttributes
,
39 Status
= RtlpNtOpenKey(&SecurityKeyHandle
,
40 KEY_READ
| KEY_CREATE_SUB_KEY
| KEY_ENUMERATE_SUB_KEYS
,
49 LsapIsDatabaseInstalled(VOID
)
51 OBJECT_ATTRIBUTES ObjectAttributes
;
52 UNICODE_STRING KeyName
;
56 RtlInitUnicodeString(&KeyName
,
59 InitializeObjectAttributes(&ObjectAttributes
,
65 Status
= RtlpNtOpenKey(&KeyHandle
,
69 if (!NT_SUCCESS(Status
))
79 LsapInstallDatabase(VOID
)
81 OBJECT_ATTRIBUTES ObjectAttributes
;
82 UNICODE_STRING KeyName
;
83 HANDLE PolicyKeyHandle
= NULL
;
84 HANDLE AccountsKeyHandle
= NULL
;
85 HANDLE DomainsKeyHandle
= NULL
;
86 HANDLE SecretsKeyHandle
= NULL
;
87 NTSTATUS Status
= STATUS_SUCCESS
;
89 TRACE("LsapInstallDatabase()\n");
91 /* Create the 'Policy' key */
92 RtlInitUnicodeString(&KeyName
,
95 InitializeObjectAttributes(&ObjectAttributes
,
101 Status
= NtCreateKey(&PolicyKeyHandle
,
108 if (!NT_SUCCESS(Status
))
110 ERR("Failed to create the 'Policy' key (Status: 0x%08lx)\n", Status
);
114 /* Create the 'Accounts' key */
115 RtlInitUnicodeString(&KeyName
,
118 InitializeObjectAttributes(&ObjectAttributes
,
120 OBJ_CASE_INSENSITIVE
,
124 Status
= NtCreateKey(&AccountsKeyHandle
,
131 if (!NT_SUCCESS(Status
))
133 ERR("Failed to create the 'Accounts' key (Status: 0x%08lx)\n", Status
);
137 /* Create the 'Domains' key */
138 RtlInitUnicodeString(&KeyName
,
141 InitializeObjectAttributes(&ObjectAttributes
,
143 OBJ_CASE_INSENSITIVE
,
147 Status
= NtCreateKey(&DomainsKeyHandle
,
154 if (!NT_SUCCESS(Status
))
156 ERR("Failed to create the 'Domains' key (Status: 0x%08lx)\n", Status
);
160 /* Create the 'Secrets' key */
161 RtlInitUnicodeString(&KeyName
,
164 InitializeObjectAttributes(&ObjectAttributes
,
166 OBJ_CASE_INSENSITIVE
,
170 Status
= NtCreateKey(&SecretsKeyHandle
,
177 if (!NT_SUCCESS(Status
))
179 ERR("Failed to create the 'Secrets' key (Status: 0x%08lx)\n", Status
);
185 if (SecretsKeyHandle
!= NULL
)
186 NtClose(SecretsKeyHandle
);
188 if (DomainsKeyHandle
!= NULL
)
189 NtClose(DomainsKeyHandle
);
191 if (AccountsKeyHandle
!= NULL
)
192 NtClose(AccountsKeyHandle
);
194 if (PolicyKeyHandle
!= NULL
)
195 NtClose(PolicyKeyHandle
);
197 TRACE("LsapInstallDatabase() done (Status: 0x%08lx)\n", Status
);
204 LsapInitDatabase(VOID
)
208 TRACE("LsapInitDatabase()\n");
210 Status
= LsapOpenServiceKey();
211 if (!NT_SUCCESS(Status
))
213 ERR("Failed to open the service key (Status: 0x%08lx)\n", Status
);
217 if (!LsapIsDatabaseInstalled())
219 Status
= LsapInstallDatabase();
220 if (!NT_SUCCESS(Status
))
222 ERR("Failed to install the LSA database (Status: 0x%08lx)\n", Status
);
227 TRACE("LsapInitDatabase() done\n");
229 return STATUS_SUCCESS
;
234 LsapCreateDbObject(LSAPR_HANDLE ParentHandle
,
237 LSA_DB_OBJECT_TYPE ObjectType
,
238 ACCESS_MASK DesiredAccess
)
240 PLSA_DB_OBJECT ParentObject
= (PLSA_DB_OBJECT
)ParentHandle
;
241 PLSA_DB_OBJECT DbObject
;
242 OBJECT_ATTRIBUTES ObjectAttributes
;
243 UNICODE_STRING KeyName
;
244 HANDLE ParentKeyHandle
;
245 HANDLE ObjectKeyHandle
;
248 if (ParentHandle
!= NULL
)
249 ParentKeyHandle
= ParentObject
->KeyHandle
;
251 ParentKeyHandle
= SecurityKeyHandle
;
253 RtlInitUnicodeString(&KeyName
,
256 InitializeObjectAttributes(&ObjectAttributes
,
258 OBJ_CASE_INSENSITIVE
,
264 Status
= NtOpenKey(&ObjectKeyHandle
,
270 Status
= NtCreateKey(&ObjectKeyHandle
,
279 if (!NT_SUCCESS(Status
))
284 DbObject
= (PLSA_DB_OBJECT
)RtlAllocateHeap(RtlGetProcessHeap(),
286 sizeof(LSA_DB_OBJECT
));
287 if (DbObject
== NULL
)
289 NtClose(ObjectKeyHandle
);
293 DbObject
->Signature
= LSAP_DB_SIGNATURE
;
294 DbObject
->RefCount
= 0;
295 DbObject
->ObjectType
= ObjectType
;
296 DbObject
->Access
= DesiredAccess
;
297 DbObject
->KeyHandle
= ObjectKeyHandle
;
298 DbObject
->ParentObject
= ParentObject
;
300 if (ParentObject
!= NULL
)
301 ParentObject
->RefCount
++;
303 return (LSAPR_HANDLE
)DbObject
;
308 LsapValidateDbObject(LSAPR_HANDLE Handle
,
309 LSA_DB_OBJECT_TYPE ObjectType
,
310 ACCESS_MASK GrantedAccess
)
312 PLSA_DB_OBJECT DbObject
= (PLSA_DB_OBJECT
)Handle
;
313 BOOLEAN bValid
= FALSE
;
317 if (DbObject
->Signature
== LSAP_DB_SIGNATURE
)
319 if ((ObjectType
== LsaDbIgnoreObject
) ||
320 (DbObject
->ObjectType
== ObjectType
))
324 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
331 return STATUS_INVALID_HANDLE
;
333 if (GrantedAccess
!= 0)
335 /* FIXME: Check for granted access rights */
338 return STATUS_SUCCESS
;
343 LsapCloseDbObject(LSAPR_HANDLE Handle
)
345 PLSA_DB_OBJECT DbObject
= (PLSA_DB_OBJECT
)Handle
;
347 if (DbObject
->RefCount
!= 0)
348 return STATUS_UNSUCCESSFUL
;
350 if (DbObject
->ParentObject
!= NULL
)
351 DbObject
->ParentObject
->RefCount
--;
353 if (DbObject
->KeyHandle
!= NULL
)
354 NtClose(DbObject
->KeyHandle
);
356 RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject
);
358 return STATUS_SUCCESS
;
363 LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject
,
364 LPWSTR AttributeName
,
365 LPVOID AttributeData
,
368 OBJECT_ATTRIBUTES ObjectAttributes
;
369 UNICODE_STRING KeyName
;
373 RtlInitUnicodeString(&KeyName
,
376 InitializeObjectAttributes(&ObjectAttributes
,
378 OBJ_CASE_INSENSITIVE
,
382 Status
= NtCreateKey(&AttributeKey
,
387 REG_OPTION_NON_VOLATILE
,
389 if (!NT_SUCCESS(Status
))
395 Status
= RtlpNtSetValueKey(AttributeKey
,
400 NtClose(AttributeKey
);
407 LsapGetObjectAttribute(PLSA_DB_OBJECT DbObject
,
408 LPWSTR AttributeName
,
409 LPVOID AttributeData
,
410 PULONG AttributeSize
)
412 OBJECT_ATTRIBUTES ObjectAttributes
;
413 UNICODE_STRING KeyName
;
418 RtlInitUnicodeString(&KeyName
,
421 InitializeObjectAttributes(&ObjectAttributes
,
423 OBJ_CASE_INSENSITIVE
,
427 Status
= NtOpenKey(&AttributeKey
,
430 if (!NT_SUCCESS(Status
))
435 ValueSize
= *AttributeSize
;
436 Status
= RtlpNtQueryValueKey(AttributeKey
,
441 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
446 if (AttributeData
== NULL
|| *AttributeSize
== 0)
448 *AttributeSize
= ValueSize
;
449 Status
== STATUS_SUCCESS
;
452 else if (*AttributeSize
< ValueSize
)
454 *AttributeSize
= ValueSize
;
455 Status
== STATUS_BUFFER_OVERFLOW
;
459 Status
= RtlpNtQueryValueKey(AttributeKey
,
464 if (NT_SUCCESS(Status
))
466 *AttributeSize
= ValueSize
;
470 NtClose(AttributeKey
);