- 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:
Eric Kohl 2012-07-22 15:12:00 +00:00
parent d62e513aad
commit 611b08e507
5 changed files with 104 additions and 132 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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,

View file

@ -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

View file

@ -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_")