- Improve SamRegCloseKey and fix all calls to it accordingly. Also replace all calls to NtClose by calls to SampRegCloseKey.
- Add a resource to protect the Samr functions from concurrent access.

svn path=/trunk/; revision=59945
This commit is contained in:
Eric Kohl 2013-09-01 15:46:00 +00:00
parent e96cf19a81
commit ac2c013400
8 changed files with 526 additions and 365 deletions

View file

@ -101,11 +101,8 @@ SampAddMemberToAlias(IN PSAM_DB_OBJECT AliasObject,
}
done:
if (MemberKeyHandle != NULL)
SampRegCloseKey(MemberKeyHandle);
if (MembersKeyHandle != NULL)
SampRegCloseKey(MembersKeyHandle);
SampRegCloseKey(&MemberKeyHandle);
SampRegCloseKey(&MembersKeyHandle);
if (MemberIdString != NULL)
LocalFree(MemberIdString);
@ -160,8 +157,7 @@ SampRemoveMemberFromAlias(IN PSAM_DB_OBJECT AliasObject,
if (ulValueCount == 0)
{
SampRegCloseKey(MemberKeyHandle);
MemberKeyHandle = NULL;
SampRegCloseKey(&MemberKeyHandle);
Status = SampRegDeleteKey(AliasObject->MembersKeyHandle,
MemberIdString);
@ -201,8 +197,7 @@ SampRemoveMemberFromAlias(IN PSAM_DB_OBJECT AliasObject,
if (ulValueCount == 0)
{
SampRegCloseKey(MembersKeyHandle);
MembersKeyHandle = NULL;
SampRegCloseKey(&MembersKeyHandle);
Status = SampRegDeleteKey(AliasObject->KeyHandle,
L"Members");
@ -214,11 +209,8 @@ SampRemoveMemberFromAlias(IN PSAM_DB_OBJECT AliasObject,
}
done:
if (MemberKeyHandle != NULL)
SampRegCloseKey(MemberKeyHandle);
if (MembersKeyHandle != NULL)
SampRegCloseKey(MembersKeyHandle);
SampRegCloseKey(&MemberKeyHandle);
SampRegCloseKey(&MembersKeyHandle);
if (MemberIdString != NULL)
LocalFree(MemberIdString);

View file

@ -162,15 +162,11 @@ done:
RtlFreeHeap(RtlGetProcessHeap(), 0, NewObject);
}
if (MembersKeyHandle != NULL)
SampRegCloseKey(MembersKeyHandle);
if (ObjectKeyHandle != NULL)
SampRegCloseKey(ObjectKeyHandle);
SampRegCloseKey(&MembersKeyHandle);
SampRegCloseKey(&ObjectKeyHandle);
}
if (ContainerKeyHandle != NULL)
SampRegCloseKey(ContainerKeyHandle);
SampRegCloseKey(&ContainerKeyHandle);
return Status;
}
@ -294,15 +290,11 @@ done:
RtlFreeHeap(RtlGetProcessHeap(), 0, NewObject);
}
if (MembersKeyHandle != NULL)
SampRegCloseKey(MembersKeyHandle);
if (ObjectKeyHandle != NULL)
SampRegCloseKey(ObjectKeyHandle);
SampRegCloseKey(&MembersKeyHandle);
SampRegCloseKey(&ObjectKeyHandle);
}
if (ContainerKeyHandle != NULL)
SampRegCloseKey(ContainerKeyHandle);
SampRegCloseKey(&ContainerKeyHandle);
return Status;
}
@ -363,11 +355,8 @@ SampCloseDbObject(PSAM_DB_OBJECT DbObject)
if (DbObject->RefCount > 0)
return STATUS_SUCCESS;
if (DbObject->KeyHandle != NULL)
SampRegCloseKey(DbObject->KeyHandle);
if (DbObject->MembersKeyHandle != NULL)
SampRegCloseKey(DbObject->MembersKeyHandle);
SampRegCloseKey(&DbObject->KeyHandle);
SampRegCloseKey(&DbObject->MembersKeyHandle);
if (DbObject->Name != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject->Name);
@ -383,8 +372,8 @@ SampDeleteAccountDbObject(PSAM_DB_OBJECT DbObject)
{
LPCWSTR ContainerName;
LPWSTR AccountName = NULL;
HKEY ContainerKey;
HKEY NamesKey;
HANDLE ContainerKey = NULL;
HANDLE NamesKey = NULL;
ULONG Length = 0;
NTSTATUS Status = STATUS_SUCCESS;
@ -441,13 +430,11 @@ SampDeleteAccountDbObject(PSAM_DB_OBJECT DbObject)
goto done;
}
if (DbObject->KeyHandle != NULL)
SampRegCloseKey(DbObject->KeyHandle);
SampRegCloseKey(&DbObject->KeyHandle);
if (DbObject->ObjectType == SamDbAliasObject)
{
if (DbObject->MembersKeyHandle != NULL)
SampRegCloseKey(DbObject->MembersKeyHandle);
SampRegCloseKey(&DbObject->MembersKeyHandle);
SampRegDeleteKey(DbObject->KeyHandle,
L"Members");
@ -503,11 +490,8 @@ SampDeleteAccountDbObject(PSAM_DB_OBJECT DbObject)
Status = STATUS_SUCCESS;
done:
if (NamesKey != NULL)
SampRegCloseKey(NamesKey);
if (ContainerKey != NULL)
SampRegCloseKey(ContainerKey);
SampRegCloseKey(&NamesKey);
SampRegCloseKey(&ContainerKey);
if (AccountName != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, AccountName);

View file

@ -21,9 +21,6 @@ SampSetAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
IN LPCWSTR lpAccountName,
IN ULONG ulRelativeId)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
UNICODE_STRING ValueName;
HANDLE ContainerKeyHandle = NULL;
HANDLE NamesKeyHandle = NULL;
NTSTATUS Status;
@ -31,51 +28,31 @@ SampSetAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
TRACE("SampSetAccountNameInDomain()\n");
/* Open the container key */
RtlInitUnicodeString(&KeyName, lpContainerName);
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
DomainObject->KeyHandle,
NULL);
Status = NtOpenKey(&ContainerKeyHandle,
KEY_ALL_ACCESS,
&ObjectAttributes);
Status = SampRegOpenKey(DomainObject->KeyHandle,
lpContainerName,
KEY_ALL_ACCESS,
&ContainerKeyHandle);
if (!NT_SUCCESS(Status))
return Status;
/* Open the 'Names' key */
RtlInitUnicodeString(&KeyName, L"Names");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
ContainerKeyHandle,
NULL);
Status = NtOpenKey(&NamesKeyHandle,
KEY_ALL_ACCESS,
&ObjectAttributes);
Status = SampRegOpenKey(ContainerKeyHandle,
L"Names",
KEY_ALL_ACCESS,
&NamesKeyHandle);
if (!NT_SUCCESS(Status))
goto done;
/* Set the alias value */
RtlInitUnicodeString(&ValueName, lpAccountName);
Status = NtSetValueKey(NamesKeyHandle,
&ValueName,
0,
REG_DWORD,
(LPVOID)&ulRelativeId,
sizeof(ULONG));
Status = SampRegSetValue(NamesKeyHandle,
lpAccountName,
REG_DWORD,
(LPVOID)&ulRelativeId,
sizeof(ULONG));
done:
if (NamesKeyHandle)
NtClose(NamesKeyHandle);
if (ContainerKeyHandle)
NtClose(ContainerKeyHandle);
SampRegCloseKey(&NamesKeyHandle);
SampRegCloseKey(&ContainerKeyHandle);
return Status;
}
@ -86,8 +63,6 @@ SampRemoveAccountNameFromDomain(IN PSAM_DB_OBJECT DomainObject,
IN LPCWSTR lpContainerName,
IN LPCWSTR lpAccountName)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
HANDLE ContainerKeyHandle = NULL;
HANDLE NamesKeyHandle = NULL;
NTSTATUS Status;
@ -95,32 +70,18 @@ SampRemoveAccountNameFromDomain(IN PSAM_DB_OBJECT DomainObject,
TRACE("(%S %S)\n", lpContainerName, lpAccountName);
/* Open the container key */
RtlInitUnicodeString(&KeyName, lpContainerName);
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
DomainObject->KeyHandle,
NULL);
Status = NtOpenKey(&ContainerKeyHandle,
KEY_ALL_ACCESS,
&ObjectAttributes);
Status = SampRegOpenKey(DomainObject->KeyHandle,
lpContainerName,
KEY_ALL_ACCESS,
&ContainerKeyHandle);
if (!NT_SUCCESS(Status))
return Status;
/* Open the 'Names' key */
RtlInitUnicodeString(&KeyName, L"Names");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
ContainerKeyHandle,
NULL);
Status = NtOpenKey(&NamesKeyHandle,
KEY_SET_VALUE,
&ObjectAttributes);
Status = SampRegOpenKey(ContainerKeyHandle,
L"Names",
KEY_SET_VALUE,
&NamesKeyHandle);
if (!NT_SUCCESS(Status))
goto done;
@ -129,11 +90,8 @@ SampRemoveAccountNameFromDomain(IN PSAM_DB_OBJECT DomainObject,
lpAccountName);
done:
if (NamesKeyHandle)
NtClose(NamesKeyHandle);
if (ContainerKeyHandle)
NtClose(ContainerKeyHandle);
SampRegCloseKey(&NamesKeyHandle);
SampRegCloseKey(&ContainerKeyHandle);
return Status;
}
@ -143,8 +101,8 @@ NTSTATUS
SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
IN LPCWSTR lpAccountName)
{
HANDLE AccountKey;
HANDLE NamesKey;
HANDLE AccountKey = NULL;
HANDLE NamesKey = NULL;
NTSTATUS Status;
TRACE("SampCheckAccountNameInDomain()\n");
@ -168,14 +126,14 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
NULL);
if (Status == STATUS_SUCCESS)
{
SampRegCloseKey(NamesKey);
SampRegCloseKey(&NamesKey);
Status = STATUS_ALIAS_EXISTS;
}
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
Status = STATUS_SUCCESS;
}
SampRegCloseKey(AccountKey);
SampRegCloseKey(&AccountKey);
}
if (!NT_SUCCESS(Status))
@ -203,14 +161,14 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
NULL);
if (Status == STATUS_SUCCESS)
{
SampRegCloseKey(NamesKey);
SampRegCloseKey(&NamesKey);
Status = STATUS_ALIAS_EXISTS;
}
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
Status = STATUS_SUCCESS;
}
SampRegCloseKey(AccountKey);
SampRegCloseKey(&AccountKey);
}
if (!NT_SUCCESS(Status))
@ -238,14 +196,14 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
NULL);
if (Status == STATUS_SUCCESS)
{
SampRegCloseKey(NamesKey);
SampRegCloseKey(&NamesKey);
Status = STATUS_ALIAS_EXISTS;
}
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
Status = STATUS_SUCCESS;
}
SampRegCloseKey(AccountKey);
SampRegCloseKey(&AccountKey);
}
if (!NT_SUCCESS(Status))
@ -263,9 +221,9 @@ SampRemoveMemberFromAllAliases(IN PSAM_DB_OBJECT DomainObject,
{
WCHAR AliasKeyName[64];
LPWSTR MemberSidString = NULL;
HANDLE AliasesKey;
HANDLE MembersKey;
HANDLE AliasKey;
HANDLE AliasesKey = NULL;
HANDLE MembersKey = NULL;
HANDLE AliasKey = NULL;
ULONG Index;
NTSTATUS Status;
@ -311,12 +269,12 @@ SampRemoveMemberFromAllAliases(IN PSAM_DB_OBJECT DomainObject,
Status = SampRegDeleteValue(AliasKey,
MemberSidString);
SampRegCloseKey(MembersKey);
SampRegCloseKey(&MembersKey);
}
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
Status = STATUS_SUCCESS;
SampRegCloseKey(AliasKey);
SampRegCloseKey(&AliasKey);
}
Index++;
@ -333,10 +291,10 @@ SampRemoveMemberFromAllAliases(IN PSAM_DB_OBJECT DomainObject,
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
Status = STATUS_SUCCESS;
SampRegCloseKey(MembersKey);
SampRegCloseKey(&MembersKey);
}
SampRegCloseKey(AliasesKey);
SampRegCloseKey(&AliasesKey);
}
if (MemberSidString != NULL)

View file

@ -24,9 +24,18 @@ IsStringType(ULONG Type)
NTSTATUS
SampRegCloseKey(IN HANDLE KeyHandle)
SampRegCloseKey(IN OUT PHANDLE KeyHandle)
{
return NtClose(KeyHandle);
NTSTATUS Status;
if (KeyHandle == NULL || *KeyHandle == NULL)
return STATUS_SUCCESS;
Status = NtClose(*KeyHandle);
if (NT_SUCCESS(Status))
*KeyHandle = NULL;
return Status;
}
@ -34,7 +43,7 @@ NTSTATUS
SampRegCreateKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle)
OUT PHANDLE KeyHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
@ -150,7 +159,7 @@ NTSTATUS
SampRegOpenKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle)
OUT PHANDLE KeyHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
ENCRYPTED_NT_OWF_PASSWORD EmptyNtHash;
ENCRYPTED_LM_OWF_PASSWORD EmptyLmHash;
RTL_RESOURCE SampResource;
/* FUNCTIONS *****************************************************************/
@ -117,6 +118,8 @@ SamIInitialize(VOID)
return Status;
}
RtlInitializeResource(&SampResource);
/* Initialize the SAM database */
Status = SampInitDatabase();
if (!NT_SUCCESS(Status))

View file

@ -121,6 +121,7 @@ typedef struct _SAM_USER_FIXED_DATA
extern PGENERIC_MAPPING pServerMapping;
extern ENCRYPTED_NT_OWF_PASSWORD EmptyNtHash;
extern ENCRYPTED_LM_OWF_PASSWORD EmptyLmHash;
extern RTL_RESOURCE SampResource;
/* alias.c */
@ -238,13 +239,13 @@ SampRemoveMemberFromGroup(IN PSAM_DB_OBJECT GroupObject,
/* registry.h */
NTSTATUS
SampRegCloseKey(IN HANDLE KeyHandle);
SampRegCloseKey(IN OUT PHANDLE KeyHandle);
NTSTATUS
SampRegCreateKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle);
OUT PHANDLE KeyHandle);
NTSTATUS
SampRegDeleteKey(IN HANDLE ParentKeyHandle,
@ -260,7 +261,7 @@ NTSTATUS
SampRegOpenKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle);
OUT PHANDLE KeyHandle);
NTSTATUS
SampRegQueryKeyInfo(IN HANDLE KeyHandle,

View file

@ -140,12 +140,11 @@ SampSetupCreateAliasAccount(HANDLE hDomainKey,
sizeof(ULONG));
done:
if (hNamesKey != NULL)
SampRegCloseKey(hNamesKey);
SampRegCloseKey(&hNamesKey);
if (hAccountKey != NULL)
{
SampRegCloseKey(hAccountKey);
SampRegCloseKey(&hAccountKey);
if (!NT_SUCCESS(Status))
SampRegDeleteKey(hDomainKey,
@ -229,8 +228,7 @@ done:
if (MembersBuffer != NULL)
midl_user_free(MembersBuffer);
if (hGroupKey != NULL)
SampRegCloseKey(hGroupKey);
SampRegCloseKey(&hGroupKey);
return Status;
}
@ -302,12 +300,11 @@ SampSetupCreateGroupAccount(HANDLE hDomainKey,
sizeof(ULONG));
done:
if (hNamesKey != NULL)
SampRegCloseKey(hNamesKey);
SampRegCloseKey(&hNamesKey);
if (hAccountKey != NULL)
{
SampRegCloseKey(hAccountKey);
SampRegCloseKey(&hAccountKey);
if (!NT_SUCCESS(Status))
SampRegDeleteKey(hDomainKey,
@ -530,12 +527,11 @@ SampSetupCreateUserAccount(HANDLE hDomainKey,
sizeof(ULONG));
done:
if (hNamesKey != NULL)
SampRegCloseKey(hNamesKey);
SampRegCloseKey(&hNamesKey);
if (hAccountKey != NULL)
{
SampRegCloseKey(hAccountKey);
SampRegCloseKey(&hAccountKey);
if (!NT_SUCCESS(Status))
SampRegDeleteKey(hDomainKey,
@ -659,7 +655,7 @@ SampSetupCreateDomain(IN HANDLE hServerKey,
if (!NT_SUCCESS(Status))
goto done;
SampRegCloseKey(hNamesKey);
SampRegCloseKey(&hNamesKey);
/* Create the Groups container */
Status = SampRegCreateKey(hDomainKey,
@ -676,7 +672,7 @@ SampSetupCreateDomain(IN HANDLE hServerKey,
if (!NT_SUCCESS(Status))
goto done;
SampRegCloseKey(hNamesKey);
SampRegCloseKey(&hNamesKey);
/* Create the Users container */
Status = SampRegCreateKey(hDomainKey,
@ -713,7 +709,7 @@ SampSetupCreateDomain(IN HANDLE hServerKey,
if (!NT_SUCCESS(Status))
goto done;
SampRegCloseKey(hNamesKey);
SampRegCloseKey(&hNamesKey);
if (lpDomainKey != NULL)
*lpDomainKey = hDomainKey;
@ -722,20 +718,12 @@ done:
if (Sd != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Sd);
if (hAliasesKey != NULL)
SampRegCloseKey(hAliasesKey);
if (hGroupsKey != NULL)
SampRegCloseKey(hGroupsKey);
if (hUsersKey != NULL)
SampRegCloseKey(hUsersKey);
SampRegCloseKey(&hAliasesKey);
SampRegCloseKey(&hGroupsKey);
SampRegCloseKey(&hUsersKey);
if (!NT_SUCCESS(Status))
{
if (hDomainKey != NULL)
SampRegCloseKey(hDomainKey);
}
SampRegCloseKey(&hDomainKey);
return Status;
}
@ -781,7 +769,7 @@ SampSetupCreateServer(IN HANDLE hSamKey,
if (!NT_SUCCESS(Status))
goto done;
SampRegCloseKey(hDomainsKey);
SampRegCloseKey(&hDomainsKey);
*lpServerKey = hServerKey;
@ -1012,17 +1000,10 @@ done:
if (pBuiltinSid)
RtlFreeHeap(RtlGetProcessHeap(), 0, pBuiltinSid);
if (hAccountDomainKey != NULL)
SampRegCloseKey(hAccountDomainKey);
if (hBuiltinDomainKey != NULL)
SampRegCloseKey(hBuiltinDomainKey);
if (hServerKey != NULL)
SampRegCloseKey(hServerKey);
if (hSamKey != NULL)
SampRegCloseKey(hSamKey);
SampRegCloseKey(&hAccountDomainKey);
SampRegCloseKey(&hBuiltinDomainKey);
SampRegCloseKey(&hServerKey);
SampRegCloseKey(&hSamKey);
TRACE("SampInitializeSAM() done\n");