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 LsapCreateDatabaseKeys(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
);
184 if (SecretsKeyHandle
!= NULL
)
185 NtClose(SecretsKeyHandle
);
187 if (DomainsKeyHandle
!= NULL
)
188 NtClose(DomainsKeyHandle
);
190 if (AccountsKeyHandle
!= NULL
)
191 NtClose(AccountsKeyHandle
);
193 if (PolicyKeyHandle
!= NULL
)
194 NtClose(PolicyKeyHandle
);
196 TRACE("LsapInstallDatabase() done (Status: 0x%08lx)\n", Status
);
203 LsapCreateDatabaseObjects(VOID
)
205 PLSA_DB_OBJECT DbObject
= NULL
;
207 /* Open the 'Policy' object */
208 DbObject
= (PLSA_DB_OBJECT
)LsapCreateDbObject(NULL
,
213 if (DbObject
!= NULL
)
215 LsapSetObjectAttribute(DbObject
,
220 LsapSetObjectAttribute(DbObject
,
225 LsapSetObjectAttribute(DbObject
,
230 LsapSetObjectAttribute(DbObject
,
236 /* Close the 'Policy' object */
237 LsapCloseDbObject((LSAPR_HANDLE
)DbObject
);
240 return STATUS_SUCCESS
;
245 LsapUpdateDatabase(VOID
)
247 return STATUS_SUCCESS
;
252 LsapInitDatabase(VOID
)
256 TRACE("LsapInitDatabase()\n");
258 Status
= LsapOpenServiceKey();
259 if (!NT_SUCCESS(Status
))
261 ERR("Failed to open the service key (Status: 0x%08lx)\n", Status
);
265 if (!LsapIsDatabaseInstalled())
267 Status
= LsapCreateDatabaseKeys();
268 if (!NT_SUCCESS(Status
))
270 ERR("Failed to create the LSA database keys (Status: 0x%08lx)\n", Status
);
274 Status
= LsapCreateDatabaseObjects();
275 if (!NT_SUCCESS(Status
))
277 ERR("Failed to create the LSA database objects (Status: 0x%08lx)\n", Status
);
283 Status
= LsapUpdateDatabase();
284 if (!NT_SUCCESS(Status
))
286 ERR("Failed to update the LSA database (Status: 0x%08lx)\n", Status
);
291 TRACE("LsapInitDatabase() done\n");
293 return STATUS_SUCCESS
;
298 LsapCreateDbObject(LSAPR_HANDLE ParentHandle
,
301 LSA_DB_OBJECT_TYPE ObjectType
,
302 ACCESS_MASK DesiredAccess
)
304 PLSA_DB_OBJECT ParentObject
= (PLSA_DB_OBJECT
)ParentHandle
;
305 PLSA_DB_OBJECT DbObject
;
306 OBJECT_ATTRIBUTES ObjectAttributes
;
307 UNICODE_STRING KeyName
;
308 HANDLE ParentKeyHandle
;
309 HANDLE ObjectKeyHandle
;
312 if (ParentHandle
!= NULL
)
313 ParentKeyHandle
= ParentObject
->KeyHandle
;
315 ParentKeyHandle
= SecurityKeyHandle
;
317 RtlInitUnicodeString(&KeyName
,
320 InitializeObjectAttributes(&ObjectAttributes
,
322 OBJ_CASE_INSENSITIVE
,
328 Status
= NtOpenKey(&ObjectKeyHandle
,
334 Status
= NtCreateKey(&ObjectKeyHandle
,
343 if (!NT_SUCCESS(Status
))
348 DbObject
= (PLSA_DB_OBJECT
)RtlAllocateHeap(RtlGetProcessHeap(),
350 sizeof(LSA_DB_OBJECT
));
351 if (DbObject
== NULL
)
353 NtClose(ObjectKeyHandle
);
357 DbObject
->Signature
= LSAP_DB_SIGNATURE
;
358 DbObject
->RefCount
= 0;
359 DbObject
->ObjectType
= ObjectType
;
360 DbObject
->Access
= DesiredAccess
;
361 DbObject
->KeyHandle
= ObjectKeyHandle
;
362 DbObject
->ParentObject
= ParentObject
;
364 if (ParentObject
!= NULL
)
365 ParentObject
->RefCount
++;
367 return (LSAPR_HANDLE
)DbObject
;
372 LsapValidateDbObject(LSAPR_HANDLE Handle
,
373 LSA_DB_OBJECT_TYPE ObjectType
,
374 ACCESS_MASK GrantedAccess
)
376 PLSA_DB_OBJECT DbObject
= (PLSA_DB_OBJECT
)Handle
;
377 BOOLEAN bValid
= FALSE
;
381 if (DbObject
->Signature
== LSAP_DB_SIGNATURE
)
383 if ((ObjectType
== LsaDbIgnoreObject
) ||
384 (DbObject
->ObjectType
== ObjectType
))
388 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
395 return STATUS_INVALID_HANDLE
;
397 if (GrantedAccess
!= 0)
399 /* FIXME: Check for granted access rights */
402 return STATUS_SUCCESS
;
407 LsapCloseDbObject(LSAPR_HANDLE Handle
)
409 PLSA_DB_OBJECT DbObject
= (PLSA_DB_OBJECT
)Handle
;
411 if (DbObject
->RefCount
!= 0)
412 return STATUS_UNSUCCESSFUL
;
414 if (DbObject
->ParentObject
!= NULL
)
415 DbObject
->ParentObject
->RefCount
--;
417 if (DbObject
->KeyHandle
!= NULL
)
418 NtClose(DbObject
->KeyHandle
);
420 RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject
);
422 return STATUS_SUCCESS
;
427 LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject
,
428 LPWSTR AttributeName
,
429 LPVOID AttributeData
,
432 OBJECT_ATTRIBUTES ObjectAttributes
;
433 UNICODE_STRING KeyName
;
437 RtlInitUnicodeString(&KeyName
,
440 InitializeObjectAttributes(&ObjectAttributes
,
442 OBJ_CASE_INSENSITIVE
,
446 Status
= NtCreateKey(&AttributeKey
,
451 REG_OPTION_NON_VOLATILE
,
453 if (!NT_SUCCESS(Status
))
459 Status
= RtlpNtSetValueKey(AttributeKey
,
464 NtClose(AttributeKey
);
471 LsapGetObjectAttribute(PLSA_DB_OBJECT DbObject
,
472 LPWSTR AttributeName
,
473 LPVOID AttributeData
,
474 PULONG AttributeSize
)
476 OBJECT_ATTRIBUTES ObjectAttributes
;
477 UNICODE_STRING KeyName
;
482 RtlInitUnicodeString(&KeyName
,
485 InitializeObjectAttributes(&ObjectAttributes
,
487 OBJ_CASE_INSENSITIVE
,
491 Status
= NtOpenKey(&AttributeKey
,
494 if (!NT_SUCCESS(Status
))
499 ValueSize
= *AttributeSize
;
500 Status
= RtlpNtQueryValueKey(AttributeKey
,
505 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
510 if (AttributeData
== NULL
|| *AttributeSize
== 0)
512 *AttributeSize
= ValueSize
;
513 Status
== STATUS_SUCCESS
;
516 else if (*AttributeSize
< ValueSize
)
518 *AttributeSize
= ValueSize
;
519 Status
== STATUS_BUFFER_OVERFLOW
;
523 Status
= RtlpNtQueryValueKey(AttributeKey
,
528 if (NT_SUCCESS(Status
))
530 *AttributeSize
= ValueSize
;
534 NtClose(AttributeKey
);