Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendatabase.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: Local Security Authority Server DLL 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: dll/win32/lsasrv/database.c 00005 * PURPOSE: LSA object database 00006 * COPYRIGHT: Copyright 2011 Eric Kohl 00007 */ 00008 00009 /* INCLUDES ****************************************************************/ 00010 00011 #include "lsasrv.h" 00012 00013 WINE_DEFAULT_DEBUG_CHANNEL(lsasrv); 00014 00015 00016 /* GLOBALS *****************************************************************/ 00017 00018 static HANDLE SecurityKeyHandle = NULL; 00019 00020 00021 /* FUNCTIONS ***************************************************************/ 00022 00023 static NTSTATUS 00024 LsapOpenServiceKey(VOID) 00025 { 00026 OBJECT_ATTRIBUTES ObjectAttributes; 00027 UNICODE_STRING KeyName; 00028 NTSTATUS Status; 00029 00030 RtlInitUnicodeString(&KeyName, 00031 L"\\Registry\\Machine\\SECURITY"); 00032 00033 InitializeObjectAttributes(&ObjectAttributes, 00034 &KeyName, 00035 OBJ_CASE_INSENSITIVE, 00036 NULL, 00037 NULL); 00038 00039 Status = RtlpNtOpenKey(&SecurityKeyHandle, 00040 KEY_READ | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, 00041 &ObjectAttributes, 00042 0); 00043 00044 return Status; 00045 } 00046 00047 00048 static BOOLEAN 00049 LsapIsDatabaseInstalled(VOID) 00050 { 00051 OBJECT_ATTRIBUTES ObjectAttributes; 00052 UNICODE_STRING KeyName; 00053 HANDLE KeyHandle; 00054 NTSTATUS Status; 00055 00056 RtlInitUnicodeString(&KeyName, 00057 L"Policy"); 00058 00059 InitializeObjectAttributes(&ObjectAttributes, 00060 &KeyName, 00061 OBJ_CASE_INSENSITIVE, 00062 SecurityKeyHandle, 00063 NULL); 00064 00065 Status = RtlpNtOpenKey(&KeyHandle, 00066 KEY_READ, 00067 &ObjectAttributes, 00068 0); 00069 if (!NT_SUCCESS(Status)) 00070 return FALSE; 00071 00072 NtClose(KeyHandle); 00073 00074 return TRUE; 00075 } 00076 00077 00078 static NTSTATUS 00079 LsapCreateDatabaseKeys(VOID) 00080 { 00081 OBJECT_ATTRIBUTES ObjectAttributes; 00082 UNICODE_STRING KeyName; 00083 HANDLE PolicyKeyHandle = NULL; 00084 HANDLE AccountsKeyHandle = NULL; 00085 HANDLE DomainsKeyHandle = NULL; 00086 HANDLE SecretsKeyHandle = NULL; 00087 NTSTATUS Status = STATUS_SUCCESS; 00088 00089 TRACE("LsapInstallDatabase()\n"); 00090 00091 /* Create the 'Policy' key */ 00092 RtlInitUnicodeString(&KeyName, 00093 L"Policy"); 00094 00095 InitializeObjectAttributes(&ObjectAttributes, 00096 &KeyName, 00097 OBJ_CASE_INSENSITIVE, 00098 SecurityKeyHandle, 00099 NULL); 00100 00101 Status = NtCreateKey(&PolicyKeyHandle, 00102 KEY_ALL_ACCESS, 00103 &ObjectAttributes, 00104 0, 00105 NULL, 00106 0, 00107 NULL); 00108 if (!NT_SUCCESS(Status)) 00109 { 00110 ERR("Failed to create the 'Policy' key (Status: 0x%08lx)\n", Status); 00111 goto Done; 00112 } 00113 00114 /* Create the 'Accounts' key */ 00115 RtlInitUnicodeString(&KeyName, 00116 L"Accounts"); 00117 00118 InitializeObjectAttributes(&ObjectAttributes, 00119 &KeyName, 00120 OBJ_CASE_INSENSITIVE, 00121 PolicyKeyHandle, 00122 NULL); 00123 00124 Status = NtCreateKey(&AccountsKeyHandle, 00125 KEY_ALL_ACCESS, 00126 &ObjectAttributes, 00127 0, 00128 NULL, 00129 0, 00130 NULL); 00131 if (!NT_SUCCESS(Status)) 00132 { 00133 ERR("Failed to create the 'Accounts' key (Status: 0x%08lx)\n", Status); 00134 goto Done; 00135 } 00136 00137 /* Create the 'Domains' key */ 00138 RtlInitUnicodeString(&KeyName, 00139 L"Domains"); 00140 00141 InitializeObjectAttributes(&ObjectAttributes, 00142 &KeyName, 00143 OBJ_CASE_INSENSITIVE, 00144 PolicyKeyHandle, 00145 NULL); 00146 00147 Status = NtCreateKey(&DomainsKeyHandle, 00148 KEY_ALL_ACCESS, 00149 &ObjectAttributes, 00150 0, 00151 NULL, 00152 0, 00153 NULL); 00154 if (!NT_SUCCESS(Status)) 00155 { 00156 ERR("Failed to create the 'Domains' key (Status: 0x%08lx)\n", Status); 00157 goto Done; 00158 } 00159 00160 /* Create the 'Secrets' key */ 00161 RtlInitUnicodeString(&KeyName, 00162 L"Secrets"); 00163 00164 InitializeObjectAttributes(&ObjectAttributes, 00165 &KeyName, 00166 OBJ_CASE_INSENSITIVE, 00167 PolicyKeyHandle, 00168 NULL); 00169 00170 Status = NtCreateKey(&SecretsKeyHandle, 00171 KEY_ALL_ACCESS, 00172 &ObjectAttributes, 00173 0, 00174 NULL, 00175 0, 00176 NULL); 00177 if (!NT_SUCCESS(Status)) 00178 { 00179 ERR("Failed to create the 'Secrets' key (Status: 0x%08lx)\n", Status); 00180 goto Done; 00181 } 00182 00183 Done: 00184 if (SecretsKeyHandle != NULL) 00185 NtClose(SecretsKeyHandle); 00186 00187 if (DomainsKeyHandle != NULL) 00188 NtClose(DomainsKeyHandle); 00189 00190 if (AccountsKeyHandle != NULL) 00191 NtClose(AccountsKeyHandle); 00192 00193 if (PolicyKeyHandle != NULL) 00194 NtClose(PolicyKeyHandle); 00195 00196 TRACE("LsapInstallDatabase() done (Status: 0x%08lx)\n", Status); 00197 00198 return Status; 00199 } 00200 00201 00202 static NTSTATUS 00203 LsapCreateDatabaseObjects(VOID) 00204 { 00205 PLSA_DB_OBJECT PolicyObject; 00206 NTSTATUS Status; 00207 00208 /* Open the 'Policy' object */ 00209 Status = LsapOpenDbObject(NULL, 00210 L"Policy", 00211 LsaDbPolicyObject, 00212 0, 00213 &PolicyObject); 00214 if (!NT_SUCCESS(Status)) 00215 return Status; 00216 00217 LsapSetObjectAttribute(PolicyObject, 00218 L"PolPrDmN", 00219 NULL, 00220 0); 00221 00222 LsapSetObjectAttribute(PolicyObject, 00223 L"PolPrDmS", 00224 NULL, 00225 0); 00226 00227 LsapSetObjectAttribute(PolicyObject, 00228 L"PolAcDmN", 00229 NULL, 00230 0); 00231 00232 LsapSetObjectAttribute(PolicyObject, 00233 L"PolAcDmS", 00234 NULL, 00235 0); 00236 00237 /* Close the 'Policy' object */ 00238 LsapCloseDbObject(PolicyObject); 00239 00240 return STATUS_SUCCESS; 00241 } 00242 00243 00244 static NTSTATUS 00245 LsapUpdateDatabase(VOID) 00246 { 00247 return STATUS_SUCCESS; 00248 } 00249 00250 00251 NTSTATUS 00252 LsapInitDatabase(VOID) 00253 { 00254 NTSTATUS Status; 00255 00256 TRACE("LsapInitDatabase()\n"); 00257 00258 Status = LsapOpenServiceKey(); 00259 if (!NT_SUCCESS(Status)) 00260 { 00261 ERR("Failed to open the service key (Status: 0x%08lx)\n", Status); 00262 return Status; 00263 } 00264 00265 if (!LsapIsDatabaseInstalled()) 00266 { 00267 Status = LsapCreateDatabaseKeys(); 00268 if (!NT_SUCCESS(Status)) 00269 { 00270 ERR("Failed to create the LSA database keys (Status: 0x%08lx)\n", Status); 00271 return Status; 00272 } 00273 00274 Status = LsapCreateDatabaseObjects(); 00275 if (!NT_SUCCESS(Status)) 00276 { 00277 ERR("Failed to create the LSA database objects (Status: 0x%08lx)\n", Status); 00278 return Status; 00279 } 00280 } 00281 else 00282 { 00283 Status = LsapUpdateDatabase(); 00284 if (!NT_SUCCESS(Status)) 00285 { 00286 ERR("Failed to update the LSA database (Status: 0x%08lx)\n", Status); 00287 return Status; 00288 } 00289 } 00290 00291 TRACE("LsapInitDatabase() done\n"); 00292 00293 return STATUS_SUCCESS; 00294 } 00295 00296 00297 NTSTATUS 00298 LsapCreateDbObject(IN PLSA_DB_OBJECT ParentObject, 00299 IN LPWSTR ObjectName, 00300 IN LSA_DB_OBJECT_TYPE ObjectType, 00301 IN ACCESS_MASK DesiredAccess, 00302 OUT PLSA_DB_OBJECT *DbObject) 00303 { 00304 PLSA_DB_OBJECT NewObject; 00305 OBJECT_ATTRIBUTES ObjectAttributes; 00306 UNICODE_STRING KeyName; 00307 HANDLE ParentKeyHandle; 00308 HANDLE ObjectKeyHandle; 00309 NTSTATUS Status; 00310 00311 if (DbObject == NULL) 00312 return STATUS_INVALID_PARAMETER; 00313 00314 if (ParentObject == NULL) 00315 ParentKeyHandle = SecurityKeyHandle; 00316 else 00317 ParentKeyHandle = ParentObject->KeyHandle; 00318 00319 RtlInitUnicodeString(&KeyName, 00320 ObjectName); 00321 00322 InitializeObjectAttributes(&ObjectAttributes, 00323 &KeyName, 00324 OBJ_CASE_INSENSITIVE, 00325 ParentKeyHandle, 00326 NULL); 00327 00328 Status = NtCreateKey(&ObjectKeyHandle, 00329 KEY_ALL_ACCESS, 00330 &ObjectAttributes, 00331 0, 00332 NULL, 00333 0, 00334 NULL); 00335 if (!NT_SUCCESS(Status)) 00336 { 00337 return Status; 00338 } 00339 00340 NewObject = RtlAllocateHeap(RtlGetProcessHeap(), 00341 0, 00342 sizeof(LSA_DB_OBJECT)); 00343 if (NewObject == NULL) 00344 { 00345 NtClose(ObjectKeyHandle); 00346 return STATUS_NO_MEMORY; 00347 } 00348 00349 NewObject->Signature = LSAP_DB_SIGNATURE; 00350 NewObject->RefCount = 1; 00351 NewObject->ObjectType = ObjectType; 00352 NewObject->Access = DesiredAccess; 00353 NewObject->KeyHandle = ObjectKeyHandle; 00354 NewObject->ParentObject = ParentObject; 00355 00356 if (ParentObject != NULL) 00357 ParentObject->RefCount++; 00358 00359 *DbObject = NewObject; 00360 00361 return STATUS_SUCCESS; 00362 } 00363 00364 00365 NTSTATUS 00366 LsapOpenDbObject(IN PLSA_DB_OBJECT ParentObject, 00367 IN LPWSTR ObjectName, 00368 IN LSA_DB_OBJECT_TYPE ObjectType, 00369 IN ACCESS_MASK DesiredAccess, 00370 OUT PLSA_DB_OBJECT *DbObject) 00371 { 00372 PLSA_DB_OBJECT NewObject; 00373 OBJECT_ATTRIBUTES ObjectAttributes; 00374 UNICODE_STRING KeyName; 00375 HANDLE ParentKeyHandle; 00376 HANDLE ObjectKeyHandle; 00377 NTSTATUS Status; 00378 00379 if (DbObject == NULL) 00380 return STATUS_INVALID_PARAMETER; 00381 00382 if (ParentObject == NULL) 00383 ParentKeyHandle = SecurityKeyHandle; 00384 else 00385 ParentKeyHandle = ParentObject->KeyHandle; 00386 00387 RtlInitUnicodeString(&KeyName, 00388 ObjectName); 00389 00390 InitializeObjectAttributes(&ObjectAttributes, 00391 &KeyName, 00392 OBJ_CASE_INSENSITIVE, 00393 ParentKeyHandle, 00394 NULL); 00395 00396 Status = NtOpenKey(&ObjectKeyHandle, 00397 KEY_ALL_ACCESS, 00398 &ObjectAttributes); 00399 if (!NT_SUCCESS(Status)) 00400 { 00401 return Status; 00402 } 00403 00404 NewObject = RtlAllocateHeap(RtlGetProcessHeap(), 00405 0, 00406 sizeof(LSA_DB_OBJECT)); 00407 if (NewObject == NULL) 00408 { 00409 NtClose(ObjectKeyHandle); 00410 return STATUS_NO_MEMORY; 00411 } 00412 00413 NewObject->Signature = LSAP_DB_SIGNATURE; 00414 NewObject->RefCount = 1; 00415 NewObject->ObjectType = ObjectType; 00416 NewObject->Access = DesiredAccess; 00417 NewObject->KeyHandle = ObjectKeyHandle; 00418 NewObject->ParentObject = ParentObject; 00419 00420 if (ParentObject != NULL) 00421 ParentObject->RefCount++; 00422 00423 *DbObject = NewObject; 00424 00425 return STATUS_SUCCESS; 00426 } 00427 00428 00429 NTSTATUS 00430 LsapValidateDbObject(LSAPR_HANDLE Handle, 00431 LSA_DB_OBJECT_TYPE ObjectType, 00432 ACCESS_MASK DesiredAccess, 00433 PLSA_DB_OBJECT *DbObject) 00434 { 00435 PLSA_DB_OBJECT LocalObject = (PLSA_DB_OBJECT)Handle; 00436 BOOLEAN bValid = FALSE; 00437 00438 _SEH2_TRY 00439 { 00440 if (LocalObject->Signature == LSAP_DB_SIGNATURE) 00441 { 00442 if ((ObjectType == LsaDbIgnoreObject) || 00443 (LocalObject->ObjectType == ObjectType)) 00444 bValid = TRUE; 00445 } 00446 } 00447 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00448 { 00449 bValid = FALSE; 00450 } 00451 _SEH2_END; 00452 00453 if (bValid == FALSE) 00454 return STATUS_INVALID_HANDLE; 00455 00456 if (DesiredAccess != 0) 00457 { 00458 /* Check for granted access rights */ 00459 if ((LocalObject->Access & DesiredAccess) != DesiredAccess) 00460 { 00461 ERR("LsapValidateDbObject access check failed %08lx %08lx\n", 00462 LocalObject->Access, DesiredAccess); 00463 return STATUS_ACCESS_DENIED; 00464 } 00465 } 00466 00467 if (DbObject != NULL) 00468 *DbObject = LocalObject; 00469 00470 return STATUS_SUCCESS; 00471 } 00472 00473 00474 NTSTATUS 00475 LsapCloseDbObject(PLSA_DB_OBJECT DbObject) 00476 { 00477 PLSA_DB_OBJECT ParentObject = NULL; 00478 NTSTATUS Status = STATUS_SUCCESS; 00479 00480 DbObject->RefCount--; 00481 00482 if (DbObject->RefCount > 0) 00483 return STATUS_SUCCESS; 00484 00485 if (DbObject->KeyHandle != NULL) 00486 NtClose(DbObject->KeyHandle); 00487 00488 if (DbObject->ParentObject != NULL) 00489 ParentObject = DbObject->ParentObject; 00490 00491 RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject); 00492 00493 if (ParentObject != NULL) 00494 { 00495 ParentObject->RefCount--; 00496 00497 if (ParentObject->RefCount == 0) 00498 Status = LsapCloseDbObject(ParentObject); 00499 } 00500 00501 return Status; 00502 } 00503 00504 00505 NTSTATUS 00506 LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject, 00507 LPWSTR AttributeName, 00508 LPVOID AttributeData, 00509 ULONG AttributeSize) 00510 { 00511 OBJECT_ATTRIBUTES ObjectAttributes; 00512 UNICODE_STRING KeyName; 00513 HANDLE AttributeKey; 00514 NTSTATUS Status; 00515 00516 RtlInitUnicodeString(&KeyName, 00517 AttributeName); 00518 00519 InitializeObjectAttributes(&ObjectAttributes, 00520 &KeyName, 00521 OBJ_CASE_INSENSITIVE, 00522 DbObject->KeyHandle, 00523 NULL); 00524 00525 Status = NtCreateKey(&AttributeKey, 00526 KEY_SET_VALUE, 00527 &ObjectAttributes, 00528 0, 00529 NULL, 00530 REG_OPTION_NON_VOLATILE, 00531 NULL); 00532 if (!NT_SUCCESS(Status)) 00533 { 00534 00535 return Status; 00536 } 00537 00538 Status = RtlpNtSetValueKey(AttributeKey, 00539 REG_NONE, 00540 AttributeData, 00541 AttributeSize); 00542 00543 NtClose(AttributeKey); 00544 00545 return Status; 00546 } 00547 00548 00549 NTSTATUS 00550 LsapGetObjectAttribute(PLSA_DB_OBJECT DbObject, 00551 LPWSTR AttributeName, 00552 LPVOID AttributeData, 00553 PULONG AttributeSize) 00554 { 00555 OBJECT_ATTRIBUTES ObjectAttributes; 00556 UNICODE_STRING KeyName; 00557 HANDLE AttributeKey; 00558 ULONG ValueSize; 00559 NTSTATUS Status; 00560 00561 RtlInitUnicodeString(&KeyName, 00562 AttributeName); 00563 00564 InitializeObjectAttributes(&ObjectAttributes, 00565 &KeyName, 00566 OBJ_CASE_INSENSITIVE, 00567 DbObject->KeyHandle, 00568 NULL); 00569 00570 Status = NtOpenKey(&AttributeKey, 00571 KEY_QUERY_VALUE, 00572 &ObjectAttributes); 00573 if (!NT_SUCCESS(Status)) 00574 { 00575 return Status; 00576 } 00577 00578 ValueSize = *AttributeSize; 00579 Status = RtlpNtQueryValueKey(AttributeKey, 00580 NULL, 00581 NULL, 00582 &ValueSize, 00583 0); 00584 if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) 00585 { 00586 goto Done; 00587 } 00588 00589 if (AttributeData == NULL || *AttributeSize == 0) 00590 { 00591 *AttributeSize = ValueSize; 00592 Status = STATUS_SUCCESS; 00593 goto Done; 00594 } 00595 else if (*AttributeSize < ValueSize) 00596 { 00597 *AttributeSize = ValueSize; 00598 Status = STATUS_BUFFER_OVERFLOW; 00599 goto Done; 00600 } 00601 00602 Status = RtlpNtQueryValueKey(AttributeKey, 00603 NULL, 00604 AttributeData, 00605 &ValueSize, 00606 0); 00607 if (NT_SUCCESS(Status)) 00608 { 00609 *AttributeSize = ValueSize; 00610 } 00611 00612 Done: 00613 NtClose(AttributeKey); 00614 00615 return Status; 00616 } 00617 00618 /* EOF */ 00619 Generated on Wed May 23 2012 04:16:52 for ReactOS by
1.7.6.1
|