From 611b08e50764f0dfdca30b068d09107e7783fa99 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 22 Jul 2012 15:12:00 +0000 Subject: [PATCH] [SAMSRV] - Ensure that account names are not in use when a new alias, group or user is created. Return a proper status code if the account name is alread in use. - Initialize logon/password related data for new user account objects. - Add missing prototypes and user account control bits to ntsam.h svn path=/trunk/; revision=56936 --- reactos/dll/win32/samsrv/database.c | 112 +++++----------------------- reactos/dll/win32/samsrv/samrpc.c | 50 ++++++++----- reactos/dll/win32/samsrv/samsrv.h | 18 ++--- reactos/include/ddk/ntsam.h | 46 +++++++++++- reactos/include/reactos/idl/sam.idl | 10 +-- 5 files changed, 104 insertions(+), 132 deletions(-) diff --git a/reactos/dll/win32/samsrv/database.c b/reactos/dll/win32/samsrv/database.c index 421ef741ff4..199b549a9db 100644 --- a/reactos/dll/win32/samsrv/database.c +++ b/reactos/dll/win32/samsrv/database.c @@ -484,10 +484,10 @@ SampCloseDbObject(PSAM_DB_OBJECT DbObject) NTSTATUS -SampSetDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject, - IN LPCWSTR lpContainerName, - IN LPCWSTR lpAliasName, - IN ULONG ulAliasValue) +SampSetAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, + IN LPCWSTR lpContainerName, + IN LPCWSTR lpAccountName, + IN ULONG ulRelativeId) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; @@ -496,6 +496,8 @@ SampSetDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject, HANDLE NamesKeyHandle = NULL; NTSTATUS Status; + TRACE("SampSetAccountNameInDomain()\n"); + /* Open the container key */ RtlInitUnicodeString(&KeyName, lpContainerName); @@ -527,13 +529,13 @@ SampSetDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject, goto done; /* Set the alias value */ - RtlInitUnicodeString(&ValueName, lpAliasName); + RtlInitUnicodeString(&ValueName, lpAccountName); Status = NtSetValueKey(NamesKeyHandle, &ValueName, 0, REG_DWORD, - (LPVOID)&ulAliasValue, + (LPVOID)&ulRelativeId, sizeof(ULONG)); done: @@ -547,87 +549,6 @@ done: } -NTSTATUS -SampCheckDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject, - IN LPCWSTR lpContainerName, - IN LPCWSTR lpAliasName, - OUT PBOOL bAliasExists) -{ - PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName; - UNICODE_STRING ValueName; - HANDLE ContainerKeyHandle = NULL; - HANDLE NamesKeyHandle = NULL; - ULONG BufferLength = sizeof(ULONG); - NTSTATUS Status; - - /* Open the container key */ - RtlInitUnicodeString(&KeyName, lpContainerName); - - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - DomainObject->KeyHandle, - NULL); - - Status = NtOpenKey(&ContainerKeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes); - 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); - if (!NT_SUCCESS(Status)) - goto done; - - /* Get the alias value */ - RtlInitUnicodeString(&ValueName, lpAliasName); - - BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data); - - /* Allocate memory for the value */ - ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); - if (ValueInfo == NULL) - return STATUS_NO_MEMORY; - - /* Query the value */ - Status = ZwQueryValueKey(NamesKeyHandle, - &ValueName, - KeyValuePartialInformation, - ValueInfo, - BufferLength, - &BufferLength); - - *bAliasExists = (Status != STATUS_OBJECT_NAME_NOT_FOUND); - - Status = STATUS_SUCCESS; - - /* Free the memory and return status */ - RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); - -done: - if (NamesKeyHandle) - NtClose(NamesKeyHandle); - - if (ContainerKeyHandle) - NtClose(ContainerKeyHandle); - - return Status; -} - - NTSTATUS SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, IN LPWSTR lpAccountName) @@ -636,7 +557,7 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, HANDLE NamesKey; NTSTATUS Status; - TRACE("SampCheckNameInDomain()\n"); + TRACE("SampCheckAccountNameInDomain()\n"); Status = SampRegOpenKey(DomainObject->KeyHandle, L"Aliases", @@ -656,11 +577,12 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, NULL, NULL); if (Status == STATUS_SUCCESS) + { + SampRegCloseKey(NamesKey); Status = STATUS_ALIAS_EXISTS; + } else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) Status = STATUS_SUCCESS; - - SampRegCloseKey(NamesKey); } SampRegCloseKey(AccountKey); @@ -690,11 +612,12 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, NULL, NULL); if (Status == STATUS_SUCCESS) + { + SampRegCloseKey(NamesKey); Status = STATUS_ALIAS_EXISTS; + } else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) Status = STATUS_SUCCESS; - - SampRegCloseKey(NamesKey); } SampRegCloseKey(AccountKey); @@ -724,11 +647,12 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, NULL, NULL); if (Status == STATUS_SUCCESS) + { + SampRegCloseKey(NamesKey); Status = STATUS_ALIAS_EXISTS; + } else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) Status = STATUS_SUCCESS; - - SampRegCloseKey(NamesKey); } SampRegCloseKey(AccountKey); diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index 4fb41b23c5e..35ebbbae2d0 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -1622,11 +1622,11 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, return Status; } - /* Add the name alias for the user object */ - Status = SampSetDbObjectNameAlias(DomainObject, - L"Groups", - Name->Buffer, - ulRid); + /* Add the account name of the user object */ + Status = SampSetAccountNameInDomain(DomainObject, + L"Groups", + Name->Buffer, + ulRid); if (!NT_SUCCESS(Status)) { TRACE("failed with status 0x%08lx\n", Status); @@ -1723,6 +1723,13 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n", DomainHandle, Name, DesiredAccess, UserHandle, RelativeId); + if (Name == NULL || + Name->Length == 0 || + Name->Buffer == NULL || + UserHandle == NULL || + RelativeId == NULL) + return STATUS_INVALID_PARAMETER; + /* Validate the domain handle */ Status = SampValidateDbObject(DomainHandle, SamDbDomainObject, @@ -1791,11 +1798,11 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, return Status; } - /* Add the name alias for the user object */ - Status = SampSetDbObjectNameAlias(DomainObject, - L"Users", - Name->Buffer, - ulRid); + /* Add the account name for the user object */ + Status = SampSetAccountNameInDomain(DomainObject, + L"Users", + Name->Buffer, + ulRid); if (!NT_SUCCESS(Status)) { TRACE("failed with status 0x%08lx\n", Status); @@ -1805,12 +1812,17 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, /* Initialize fixed user data */ memset(&FixedUserData, 0, sizeof(SAM_USER_FIXED_DATA)); FixedUserData.Version = 1; - + FixedUserData.LastLogon.QuadPart = 0; + FixedUserData.LastLogoff.QuadPart = 0; + FixedUserData.PasswordLastSet.QuadPart = 0; + FixedUserData.AccountExpires.LowPart = MAXULONG; + FixedUserData.AccountExpires.HighPart = MAXLONG; + FixedUserData.LastBadPasswordTime.QuadPart = 0; FixedUserData.UserId = ulRid; FixedUserData.PrimaryGroupId = DOMAIN_GROUP_RID_USERS; -// FixedUserData.UserAccountControl = USER_ACCOUNT_DISABLED | -// USER_PASSWORD_NOT_REQUIRED || -// USER_NORMAL_ACCOUNT; + FixedUserData.UserAccountControl = USER_ACCOUNT_DISABLED | + USER_PASSWORD_NOT_REQUIRED | + USER_NORMAL_ACCOUNT; /* Set fixed user data attribute */ Status = SampSetObjectAttribute(UserObject, @@ -2050,11 +2062,11 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, return Status; } - /* Add the name alias for the user object */ - Status = SampSetDbObjectNameAlias(DomainObject, - L"Aliases", - AccountName->Buffer, - ulRid); + /* Add the account name for the alias object */ + Status = SampSetAccountNameInDomain(DomainObject, + L"Aliases", + AccountName->Buffer, + ulRid); if (!NT_SUCCESS(Status)) { TRACE("failed with status 0x%08lx\n", Status); diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index ce441eafb3f..c7e54add732 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -138,22 +138,16 @@ SampValidateDbObject(SAMPR_HANDLE Handle, NTSTATUS SampCloseDbObject(PSAM_DB_OBJECT DbObject); -NTSTATUS -SampSetDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject, - IN LPCWSTR lpContainerName, - IN LPCWSTR lpAliasName, - IN DWORD dwAliasValue); - -NTSTATUS -SampCheckDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject, - IN LPCWSTR lpContainerName, - IN LPCWSTR lpAliasName, - OUT PBOOL bAliasExists); - NTSTATUS SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, IN LPWSTR lpAccountName); +NTSTATUS +SampSetAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, + IN LPCWSTR lpContainerName, + IN LPCWSTR lpAccountName, + IN ULONG ulRelativeId); + NTSTATUS SampSetObjectAttribute(PSAM_DB_OBJECT DbObject, LPWSTR AttributeName, diff --git a/reactos/include/ddk/ntsam.h b/reactos/include/ddk/ntsam.h index 1e13410d982..3ff860e9be0 100644 --- a/reactos/include/ddk/ntsam.h +++ b/reactos/include/ddk/ntsam.h @@ -163,6 +163,31 @@ extern "C" { USER_READ_GROUP_INFORMATION |\ USER_WRITE_GROUP_INFORMATION) +/* User account control bits */ +#define USER_ACCOUNT_DISABLED 0x00000001 +#define USER_HOME_DIRECTORY_REQUIRED 0x00000002 +#define USER_PASSWORD_NOT_REQUIRED 0x00000004 +#define USER_TEMP_DUPLICATE_ACCOUNT 0x00000008 +#define USER_NORMAL_ACCOUNT 0x00000010 +#define USER_MNS_LOGON_ACCOUNT 0x00000020 +#define USER_INTERDOMAIN_TRUST_ACCOUNT 0x00000040 +#define USER_WORKSTATION_TRUST_ACCOUNT 0x00000080 +#define USER_SERVER_TRUST_ACCOUNT 0x00000100 +#define USER_DONT_EXPIRE_PASSWORD 0x00000200 +#define USER_ACCOUNT_AUTO_LOCKED 0x00000400 +#define USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000800 +#define USER_SMARTCARD_REQUIRED 0x00001000 +#define USER_TRUSTED_FOR_DELEGATION 0x00002000 +#define USER_NOT_DELEGATED 0x00004000 +#define USER_USE_DES_KEY_ONLY 0x00008000 +#define USER_DONT_REQUIRE_PREAUTH 0x00010000 +#define USER_PASSWORD_EXPIRED 0x00020000 +#define USER_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x00040000 +#define USER_NO_AUTH_DATA_REQUIRED 0x00080000 +#define USER_PARTIAL_SECRETS_ACCOUNT 0x00100000 +#define USER_USE_AES_KEYS 0x00200000 + + typedef PVOID SAM_HANDLE, *PSAM_HANDLE; typedef ULONG SAM_ENUMERATE_HANDLE, *PSAM_ENUMERATE_HANDLE; @@ -291,6 +316,12 @@ NTAPI SamAddMemberToAlias(IN SAM_HANDLE AliasHandle, IN PSID MemberId); +NTSTATUS +NTAPI +SamAddMemberToGroup(IN SAM_HANDLE GroupHandle, + IN ULONG MemberId, + IN ULONG Attributes); + NTSTATUS NTAPI SamCloseHandle(IN SAM_HANDLE SamHandle); @@ -414,6 +445,12 @@ SamQueryInformationDomain(IN SAM_HANDLE DomainHandle, IN DOMAIN_INFORMATION_CLASS DomainInformationClass, OUT PVOID *Buffer); +NTSTATUS +NTAPI +SamQueryInformationGroup(IN SAM_HANDLE GroupHandle, + IN GROUP_INFORMATION_CLASS GroupInformationClass, + OUT PVOID *Buffer); + NTSTATUS NTAPI SamQueryInformationUser(IN SAM_HANDLE UserHandle, @@ -435,7 +472,13 @@ NTSTATUS NTAPI SamSetInformationDomain(IN SAM_HANDLE DomainHandle, IN DOMAIN_INFORMATION_CLASS DomainInformationClass, - IN PVOID DomainInformation); + IN PVOID Buffer); + +NTSTATUS +NTAPI +SamSetInformationGroup(IN SAM_HANDLE GroupHandle, + IN GROUP_INFORMATION_CLASS GroupInformationClass, + IN PVOID Buffer); NTSTATUS NTAPI @@ -447,7 +490,6 @@ NTSTATUS NTAPI SamShutdownSamServer(IN SAM_HANDLE ServerHandle); - #ifdef __cplusplus } #endif diff --git a/reactos/include/reactos/idl/sam.idl b/reactos/include/reactos/idl/sam.idl index 90d5406d04a..3ff5467f808 100644 --- a/reactos/include/reactos/idl/sam.idl +++ b/reactos/include/reactos/idl/sam.idl @@ -628,9 +628,9 @@ typedef struct _SAMPR_USER_INTERNAL1_INFORMATION { ENCRYPTED_NT_OWF_PASSWORD EncryptedNtOwfPassword; ENCRYPTED_LM_OWF_PASSWORD EncryptedLmOwfPassword; - unsigned char NtPasswordPresent; - unsigned char LmPasswordPresent; - unsigned char PasswordExpired; + BOOLEAN NtPasswordPresent; + BOOLEAN LmPasswordPresent; + BOOLEAN PasswordExpired; } SAMPR_USER_INTERNAL1_INFORMATION, *PSAMPR_USER_INTERNAL1_INFORMATION; typedef struct _SAMPR_USER_INTERNAL4_INFORMATION @@ -648,13 +648,13 @@ typedef struct _SAMPR_USER_INTERNAL4_INFORMATION_NEW typedef struct _SAMPR_USER_INTERNAL5_INFORMATION { SAMPR_ENCRYPTED_USER_PASSWORD UserPassword; - unsigned char PasswordExpired; + BOOLEAN PasswordExpired; } SAMPR_USER_INTERNAL5_INFORMATION, *PSAMPR_USER_INTERNAL5_INFORMATION; typedef struct _SAMPR_USER_INTERNAL5_INFORMATION_NEW { SAMPR_ENCRYPTED_USER_PASSWORD_NEW UserPassword; - unsigned char PasswordExpired; + BOOLEAN PasswordExpired; } SAMPR_USER_INTERNAL5_INFORMATION_NEW, *PSAMPR_USER_INTERNAL5_INFORMATION_NEW; cpp_quote("#ifndef _NTSAM_")