mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 13:35:47 +00:00
[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
This commit is contained in:
parent
d62e513aad
commit
611b08e507
5 changed files with 104 additions and 132 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue