From a529ab3a74157ff3b58141e3e013e58e7c393413 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Fri, 20 Jul 2012 20:42:53 +0000 Subject: [PATCH] [SAMSRV] Check if the name of a new account (alias, group or user) is used before the account is created. This check is needed because account names must be unique. svn path=/trunk/; revision=56917 --- reactos/dll/win32/samsrv/database.c | 115 ++++++++++++++++++++++++++++ reactos/dll/win32/samsrv/samrpc.c | 72 ++++++++--------- reactos/dll/win32/samsrv/samsrv.h | 4 + 3 files changed, 153 insertions(+), 38 deletions(-) diff --git a/reactos/dll/win32/samsrv/database.c b/reactos/dll/win32/samsrv/database.c index c7fdbc104bb..421ef741ff4 100644 --- a/reactos/dll/win32/samsrv/database.c +++ b/reactos/dll/win32/samsrv/database.c @@ -628,6 +628,121 @@ done: } +NTSTATUS +SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, + IN LPWSTR lpAccountName) +{ + HANDLE AccountKey; + HANDLE NamesKey; + NTSTATUS Status; + + TRACE("SampCheckNameInDomain()\n"); + + Status = SampRegOpenKey(DomainObject->KeyHandle, + L"Aliases", + KEY_READ, + &AccountKey); + if (NT_SUCCESS(Status)) + { + Status = SampRegOpenKey(AccountKey, + L"Names", + KEY_READ, + &NamesKey); + if (NT_SUCCESS(Status)) + { + Status = SampRegQueryValue(NamesKey, + lpAccountName, + NULL, + NULL, + NULL); + if (Status == STATUS_SUCCESS) + Status = STATUS_ALIAS_EXISTS; + else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + Status = STATUS_SUCCESS; + + SampRegCloseKey(NamesKey); + } + + SampRegCloseKey(AccountKey); + } + + if (!NT_SUCCESS(Status)) + { + TRACE("Checking for alias account failed (Status 0x%08lx)\n", Status); + return Status; + } + + Status = SampRegOpenKey(DomainObject->KeyHandle, + L"Groups", + KEY_READ, + &AccountKey); + if (NT_SUCCESS(Status)) + { + Status = SampRegOpenKey(AccountKey, + L"Names", + KEY_READ, + &NamesKey); + if (NT_SUCCESS(Status)) + { + Status = SampRegQueryValue(NamesKey, + lpAccountName, + NULL, + NULL, + NULL); + if (Status == STATUS_SUCCESS) + Status = STATUS_ALIAS_EXISTS; + else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + Status = STATUS_SUCCESS; + + SampRegCloseKey(NamesKey); + } + + SampRegCloseKey(AccountKey); + } + + if (!NT_SUCCESS(Status)) + { + TRACE("Checking for group account failed (Status 0x%08lx)\n", Status); + return Status; + } + + Status = SampRegOpenKey(DomainObject->KeyHandle, + L"Users", + KEY_READ, + &AccountKey); + if (NT_SUCCESS(Status)) + { + Status = SampRegOpenKey(AccountKey, + L"Names", + KEY_READ, + &NamesKey); + if (NT_SUCCESS(Status)) + { + Status = SampRegQueryValue(NamesKey, + lpAccountName, + NULL, + NULL, + NULL); + if (Status == STATUS_SUCCESS) + Status = STATUS_ALIAS_EXISTS; + else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + Status = STATUS_SUCCESS; + + SampRegCloseKey(NamesKey); + } + + SampRegCloseKey(AccountKey); + } + + if (!NT_SUCCESS(Status)) + { + TRACE("Checking for user account failed (Status 0x%08lx)\n", Status); + } + + return Status; +} + + NTSTATUS SampSetObjectAttribute(PSAM_DB_OBJECT DbObject, LPWSTR AttributeName, diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index 0b896fa4f8b..4fb41b23c5e 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -1565,6 +1565,16 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, return Status; } + /* Check if the group name already exists in the domain */ + Status = SampCheckAccountNameInDomain(DomainObject, + Name->Buffer); + if (!NT_SUCCESS(Status)) + { + TRACE("Group name \'%S\' already exists in domain (Status 0x%08lx)\n", + Name->Buffer, Status); + return Status; + } + /* Get the fixed domain attributes */ ulSize = sizeof(SAM_DOMAIN_FIXED_DATA); Status = SampGetObjectAttribute(DomainObject, @@ -1599,8 +1609,6 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, /* Convert the RID into a string (hex) */ swprintf(szRid, L"%08lX", ulRid); - /* FIXME: Check whether the group name is already in use */ - /* Create the group object */ Status = SampCreateDbObject(DomainObject, L"Groups", @@ -1710,7 +1718,6 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, ULONG ulSize; ULONG ulRid; WCHAR szRid[9]; - BOOL bAliasExists = FALSE; NTSTATUS Status; TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n", @@ -1727,6 +1734,16 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, return Status; } + /* Check if the user name already exists in the domain */ + Status = SampCheckAccountNameInDomain(DomainObject, + Name->Buffer); + if (!NT_SUCCESS(Status)) + { + TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n", + Name->Buffer, Status); + return Status; + } + /* Get the fixed domain attributes */ ulSize = sizeof(SAM_DOMAIN_FIXED_DATA); Status = SampGetObjectAttribute(DomainObject, @@ -1761,23 +1778,6 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, /* Convert the RID into a string (hex) */ swprintf(szRid, L"%08lX", ulRid); - /* Check whether the user name is already in use */ - Status = SampCheckDbObjectNameAlias(DomainObject, - L"Users", - Name->Buffer, - &bAliasExists); - if (!NT_SUCCESS(Status)) - { - TRACE("failed with status 0x%08lx\n", Status); - return Status; - } - - if (bAliasExists) - { - TRACE("The user account %S already exists!\n", Name->Buffer); - return STATUS_USER_EXISTS; - } - /* Create the user object */ Status = SampCreateDbObject(DomainObject, L"Users", @@ -1807,6 +1807,10 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, FixedUserData.Version = 1; FixedUserData.UserId = ulRid; + FixedUserData.PrimaryGroupId = DOMAIN_GROUP_RID_USERS; +// FixedUserData.UserAccountControl = USER_ACCOUNT_DISABLED | +// USER_PASSWORD_NOT_REQUIRED || +// USER_NORMAL_ACCOUNT; /* Set fixed user data attribute */ Status = SampSetObjectAttribute(UserObject, @@ -1973,7 +1977,6 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, ULONG ulSize; ULONG ulRid; WCHAR szRid[9]; - BOOL bAliasExists = FALSE; NTSTATUS Status; TRACE("SamrCreateAliasInDomain(%p %p %lx %p %p)\n", @@ -1990,6 +1993,16 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, return Status; } + /* Check if the alias name already exists in the domain */ + Status = SampCheckAccountNameInDomain(DomainObject, + AccountName->Buffer); + if (!NT_SUCCESS(Status)) + { + TRACE("Alias name \'%S\' already exists in domain (Status 0x%08lx)\n", + AccountName->Buffer, Status); + return Status; + } + /* Get the fixed domain attributes */ ulSize = sizeof(SAM_DOMAIN_FIXED_DATA); Status = SampGetObjectAttribute(DomainObject, @@ -2024,23 +2037,6 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, /* Convert the RID into a string (hex) */ swprintf(szRid, L"%08lX", ulRid); - /* Check whether the user name is already in use */ - Status = SampCheckDbObjectNameAlias(DomainObject, - L"Aliases", - AccountName->Buffer, - &bAliasExists); - if (!NT_SUCCESS(Status)) - { - TRACE("failed with status 0x%08lx\n", Status); - return Status; - } - - if (bAliasExists) - { - TRACE("The alias account %S already exists!\n", AccountName->Buffer); - return STATUS_ALIAS_EXISTS; - } - /* Create the alias object */ Status = SampCreateDbObject(DomainObject, L"Aliases", diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index 6d83b4e22df..ce441eafb3f 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -150,6 +150,10 @@ SampCheckDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject, IN LPCWSTR lpAliasName, OUT PBOOL bAliasExists); +NTSTATUS +SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, + IN LPWSTR lpAccountName); + NTSTATUS SampSetObjectAttribute(PSAM_DB_OBJECT DbObject, LPWSTR AttributeName,