- Store all fixed size user attributes in the registry value "F".
- Initialize fixed size domain attributes in SampCreateUserAccount and SamrCreateUserInDomain.
- Implement most information classes of SamrQueryInformationUser.
- Disable all informationclasses of SamrSetInformationUser that store fixed size attributes.

svn path=/trunk/; revision=56820
This commit is contained in:
Eric Kohl 2012-07-02 23:09:20 +00:00
parent 470e9cf3bf
commit 2f6a92ccd0
3 changed files with 846 additions and 3 deletions

View file

@ -1712,6 +1712,7 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
OUT unsigned long *RelativeId)
{
SAM_DOMAIN_FIXED_DATA FixedDomainData;
SAM_USER_FIXED_DATA FixedUserData;
PSAM_DB_OBJECT DomainObject;
PSAM_DB_OBJECT UserObject;
ULONG ulSize;
@ -1809,6 +1810,24 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
return Status;
}
/* Initialize fixed user data */
memset(&FixedUserData, 0, sizeof(SAM_USER_FIXED_DATA));
FixedUserData.Version = 1;
FixedUserData.UserId = ulRid;
/* Set fixed user data attribute */
Status = SampSetObjectAttribute(UserObject,
L"F",
REG_BINARY,
(LPVOID)&FixedUserData,
sizeof(SAM_USER_FIXED_DATA));
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the name attribute */
Status = SampSetObjectAttribute(UserObject,
L"Name",
@ -3158,15 +3177,720 @@ SamrDeleteUser(IN OUT SAMPR_HANDLE *UserHandle)
return STATUS_NOT_IMPLEMENTED;
}
static
NTSTATUS
SampQueryUserName(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = SampGetObjectAttribute(UserObject,
L"Name",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
InfoBuffer->Name.UserName.Length = Length - sizeof(WCHAR);
InfoBuffer->Name.UserName.MaximumLength = Length;
InfoBuffer->Name.UserName.Buffer = midl_user_allocate(Length);
if (InfoBuffer->Name.UserName.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
TRACE("Length: %lu\n", Length);
Status = SampGetObjectAttribute(UserObject,
L"Name",
NULL,
(PVOID)InfoBuffer->Name.UserName.Buffer,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
Length = 0;
Status = SampGetObjectAttribute(UserObject,
L"FullName",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
InfoBuffer->Name.FullName.Length = Length - sizeof(WCHAR);
InfoBuffer->Name.FullName.MaximumLength = Length;
InfoBuffer->Name.FullName.Buffer = midl_user_allocate(Length);
if (InfoBuffer->Name.FullName.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
TRACE("Length: %lu\n", Length);
Status = SampGetObjectAttribute(UserObject,
L"FullName",
NULL,
(PVOID)InfoBuffer->Name.FullName.Buffer,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
if (InfoBuffer->Name.UserName.Buffer != NULL)
midl_user_free(InfoBuffer->Name.UserName.Buffer);
if (InfoBuffer->Name.FullName.Buffer != NULL)
midl_user_free(InfoBuffer->Name.FullName.Buffer);
midl_user_free(InfoBuffer);
}
}
return Status;
}
static NTSTATUS
SampQueryUserAccountName(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = SampGetObjectAttribute(UserObject,
L"Name",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
InfoBuffer->AccountName.UserName.Length = Length - sizeof(WCHAR);
InfoBuffer->AccountName.UserName.MaximumLength = Length;
InfoBuffer->AccountName.UserName.Buffer = midl_user_allocate(Length);
if (InfoBuffer->AccountName.UserName.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
TRACE("Length: %lu\n", Length);
Status = SampGetObjectAttribute(UserObject,
L"Name",
NULL,
(PVOID)InfoBuffer->AccountName.UserName.Buffer,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
if (InfoBuffer->AccountName.UserName.Buffer != NULL)
midl_user_free(InfoBuffer->AccountName.UserName.Buffer);
midl_user_free(InfoBuffer);
}
}
return Status;
}
static NTSTATUS
SampQueryUserFullName(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = SampGetObjectAttribute(UserObject,
L"FullName",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
InfoBuffer->FullName.FullName.Length = Length - sizeof(WCHAR);
InfoBuffer->FullName.FullName.MaximumLength = Length;
InfoBuffer->FullName.FullName.Buffer = midl_user_allocate(Length);
if (InfoBuffer->FullName.FullName.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
TRACE("Length: %lu\n", Length);
Status = SampGetObjectAttribute(UserObject,
L"FullName",
NULL,
(PVOID)InfoBuffer->FullName.FullName.Buffer,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
if (InfoBuffer->FullName.FullName.Buffer != NULL)
midl_user_free(InfoBuffer->FullName.FullName.Buffer);
midl_user_free(InfoBuffer);
}
}
return Status;
}
static
NTSTATUS
SampQueryUserPrimaryGroup(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
SAM_USER_FIXED_DATA FixedData;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Length = sizeof(SAM_USER_FIXED_DATA);
Status = SampGetObjectAttribute(UserObject,
L"F",
NULL,
(PVOID)&FixedData,
&Length);
if (!NT_SUCCESS(Status))
goto done;
InfoBuffer->PrimaryGroup.PrimaryGroupId = FixedData.PrimaryGroupId;
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
midl_user_free(InfoBuffer);
}
}
return Status;
}
static NTSTATUS
SampQueryUserHome(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = SampGetObjectAttribute(UserObject,
L"HomeDirectory",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
InfoBuffer->Home.HomeDirectory.Length = Length - sizeof(WCHAR);
InfoBuffer->Home.HomeDirectory.MaximumLength = Length;
InfoBuffer->Home.HomeDirectory.Buffer = midl_user_allocate(Length);
if (InfoBuffer->Home.HomeDirectory.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
TRACE("Length: %lu\n", Length);
Status = SampGetObjectAttribute(UserObject,
L"HomeDirectory",
NULL,
(PVOID)InfoBuffer->Home.HomeDirectory.Buffer,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
Length = 0;
Status = SampGetObjectAttribute(UserObject,
L"HomeDirectoryDrive",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
InfoBuffer->Home.HomeDirectoryDrive.Length = Length - sizeof(WCHAR);
InfoBuffer->Home.HomeDirectoryDrive.MaximumLength = Length;
InfoBuffer->Home.HomeDirectoryDrive.Buffer = midl_user_allocate(Length);
if (InfoBuffer->Home.HomeDirectoryDrive.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
TRACE("Length: %lu\n", Length);
Status = SampGetObjectAttribute(UserObject,
L"HomeDirectoryDrive",
NULL,
(PVOID)InfoBuffer->Home.HomeDirectoryDrive.Buffer,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
if (InfoBuffer->Home.HomeDirectory.Buffer != NULL)
midl_user_free(InfoBuffer->Home.HomeDirectory.Buffer);
if (InfoBuffer->Home.HomeDirectoryDrive.Buffer != NULL)
midl_user_free(InfoBuffer->Home.HomeDirectoryDrive.Buffer);
midl_user_free(InfoBuffer);
}
}
return Status;
}
static NTSTATUS
SampQueryUserScript(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = SampGetObjectAttribute(UserObject,
L"ScriptPath",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
InfoBuffer->Script.ScriptPath.Length = Length - sizeof(WCHAR);
InfoBuffer->Script.ScriptPath.MaximumLength = Length;
InfoBuffer->Script.ScriptPath.Buffer = midl_user_allocate(Length);
if (InfoBuffer->Script.ScriptPath.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
TRACE("Length: %lu\n", Length);
Status = SampGetObjectAttribute(UserObject,
L"ScriptPath",
NULL,
(PVOID)InfoBuffer->Script.ScriptPath.Buffer,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
if (InfoBuffer->Script.ScriptPath.Buffer != NULL)
midl_user_free(InfoBuffer->Script.ScriptPath.Buffer);
midl_user_free(InfoBuffer);
}
}
return Status;
}
static NTSTATUS
SampQueryUserProfile(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = SampGetObjectAttribute(UserObject,
L"ProfilePath",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
InfoBuffer->Profile.ProfilePath.Length = Length - sizeof(WCHAR);
InfoBuffer->Profile.ProfilePath.MaximumLength = Length;
InfoBuffer->Profile.ProfilePath.Buffer = midl_user_allocate(Length);
if (InfoBuffer->Profile.ProfilePath.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
TRACE("Length: %lu\n", Length);
Status = SampGetObjectAttribute(UserObject,
L"ProfilePath",
NULL,
(PVOID)InfoBuffer->Profile.ProfilePath.Buffer,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
if (InfoBuffer->Profile.ProfilePath.Buffer != NULL)
midl_user_free(InfoBuffer->Profile.ProfilePath.Buffer);
midl_user_free(InfoBuffer);
}
}
return Status;
}
static NTSTATUS
SampQueryUserAdminComment(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = SampGetObjectAttribute(UserObject,
L"AdminComment",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
InfoBuffer->AdminComment.AdminComment.Length = Length - sizeof(WCHAR);
InfoBuffer->AdminComment.AdminComment.MaximumLength = Length;
InfoBuffer->AdminComment.AdminComment.Buffer = midl_user_allocate(Length);
if (InfoBuffer->AdminComment.AdminComment.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
TRACE("Length: %lu\n", Length);
Status = SampGetObjectAttribute(UserObject,
L"AdminComment",
NULL,
(PVOID)InfoBuffer->AdminComment.AdminComment.Buffer,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
if (InfoBuffer->AdminComment.AdminComment.Buffer != NULL)
midl_user_free(InfoBuffer->AdminComment.AdminComment.Buffer);
midl_user_free(InfoBuffer);
}
}
return Status;
}
static NTSTATUS
SampQueryUserWorkStations(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = SampGetObjectAttribute(UserObject,
L"WorkStations",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
InfoBuffer->WorkStations.WorkStations.Length = Length - sizeof(WCHAR);
InfoBuffer->WorkStations.WorkStations.MaximumLength = Length;
InfoBuffer->WorkStations.WorkStations.Buffer = midl_user_allocate(Length);
if (InfoBuffer->WorkStations.WorkStations.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
TRACE("Length: %lu\n", Length);
Status = SampGetObjectAttribute(UserObject,
L"WorkStations",
NULL,
(PVOID)InfoBuffer->WorkStations.WorkStations.Buffer,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
if (InfoBuffer->WorkStations.WorkStations.Buffer != NULL)
midl_user_free(InfoBuffer->WorkStations.WorkStations.Buffer);
midl_user_free(InfoBuffer);
}
}
return Status;
}
static
NTSTATUS
SampQueryUserControl(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
SAM_USER_FIXED_DATA FixedData;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Length = sizeof(SAM_USER_FIXED_DATA);
Status = SampGetObjectAttribute(UserObject,
L"F",
NULL,
(PVOID)&FixedData,
&Length);
if (!NT_SUCCESS(Status))
goto done;
InfoBuffer->Control.UserAccountControl = FixedData.UserAccountControl;
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
midl_user_free(InfoBuffer);
}
}
return Status;
}
static
NTSTATUS
SampQueryUserExpires(PSAM_DB_OBJECT UserObject,
PSAMPR_USER_INFO_BUFFER *Buffer)
{
PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL;
SAM_USER_FIXED_DATA FixedData;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Length = sizeof(SAM_USER_FIXED_DATA);
Status = SampGetObjectAttribute(UserObject,
L"F",
NULL,
(PVOID)&FixedData,
&Length);
if (!NT_SUCCESS(Status))
goto done;
InfoBuffer->Expires.AccountExpires.LowPart = FixedData.AccountExpires.LowPart;
InfoBuffer->Expires.AccountExpires.HighPart = FixedData.AccountExpires.HighPart;
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
midl_user_free(InfoBuffer);
}
}
return Status;
}
/* Function 36 */
NTSTATUS
NTAPI
@ -3192,6 +3916,31 @@ SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle,
DesiredAccess = USER_READ_GENERAL;
break;
case UserLogonHoursInformation:
case UserHomeInformation:
case UserScriptInformation:
case UserProfileInformation:
case UserWorkStationsInformation:
DesiredAccess = USER_READ_LOGON;
break;
case UserControlInformation:
case UserExpiresInformation:
DesiredAccess = USER_READ_ACCOUNT;
break;
case UserPreferencesInformation:
DesiredAccess = USER_READ_GENERAL |
USER_READ_PREFERENCES;
break;
case UserLogonInformation:
case UserAccountInformation:
DesiredAccess = USER_READ_GENERAL |
USER_READ_PREFERENCES |
USER_READ_LOGON |
USER_READ_ACCOUNT;
break;
default:
return STATUS_INVALID_INFO_CLASS;
@ -3210,11 +3959,66 @@ SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle,
switch (UserInformationClass)
{
// case UserGeneralInformation:
// case UserPreferencesInformation:
// case UserLogonInformation:
// case UserLogonHoursInformation:
// case UserAccountInformation:
case UserNameInformation:
Status = SampQueryUserName(UserObject,
Buffer);
break;
case UserAccountNameInformation:
Status = SampQueryUserAccountName(UserObject,
Buffer);
break;
case UserFullNameInformation:
Status = SampQueryUserFullName(UserObject,
Buffer);
break;
case UserPrimaryGroupInformation:
Status = SampQueryUserPrimaryGroup(UserObject,
Buffer);
break;
case UserHomeInformation:
Status = SampQueryUserHome(UserObject,
Buffer);
case UserScriptInformation:
Status = SampQueryUserScript(UserObject,
Buffer);
break;
case UserProfileInformation:
Status = SampQueryUserProfile(UserObject,
Buffer);
break;
case UserAdminCommentInformation:
Status = SampQueryUserAdminComment(UserObject,
Buffer);
break;
case UserWorkStationsInformation:
Status = SampQueryUserWorkStations(UserObject,
Buffer);
break;
case UserControlInformation:
Status = SampQueryUserControl(UserObject,
Buffer);
break;
case UserExpiresInformation:
Status = SampQueryUserExpires(UserObject,
Buffer);
break;
default:
Status = STATUS_INVALID_INFO_CLASS;
}
@ -3309,6 +4113,7 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle,
Buffer->FullName.FullName.MaximumLength);
break;
/*
case UserPrimaryGroupInformation:
Status = SampSetObjectAttribute(UserObject,
L"PrimaryGroupId",
@ -3316,6 +4121,7 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle,
&Buffer->PrimaryGroup.PrimaryGroupId,
sizeof(ULONG));
break;
*/
case UserHomeInformation:
Status = SampSetObjectAttribute(UserObject,
@ -3376,6 +4182,7 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle,
Buffer->SetPassword.Password.MaximumLength);
break;
/*
case UserControlInformation:
Status = SampSetObjectAttribute(UserObject,
L"UserAccountControl",
@ -3383,7 +4190,8 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle,
&Buffer->Control.UserAccountControl,
sizeof(ULONG));
break;
*/
/*
case UserExpiresInformation:
Status = SampSetObjectAttribute(UserObject,
L"AccountExpires",
@ -3391,6 +4199,7 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle,
&Buffer->Expires.AccountExpires,
sizeof(OLD_LARGE_INTEGER));
break;
*/
// case UserInternal1Information:
// case UserParametersInformation:

View file

@ -73,6 +73,26 @@ typedef struct _SAM_DOMAIN_FIXED_DATA
BOOLEAN UasCompatibilityRequired;
} SAM_DOMAIN_FIXED_DATA, *PSAM_DOMAIN_FIXED_DATA;
typedef struct _SAM_USER_FIXED_DATA
{
ULONG Version;
ULONG Reserved;
LARGE_INTEGER LastLogon;
LARGE_INTEGER LastLogoff;
LARGE_INTEGER PasswordLastSet;
LARGE_INTEGER AccountExpires;
LARGE_INTEGER LastBadPasswordTime;
ULONG UserId;
ULONG PrimaryGroupId;
ULONG UserAccountControl;
USHORT CountryCode;
USHORT CodePage;
USHORT BadPasswordCount;
USHORT LogonCount;
USHORT AdminCount;
USHORT OperatorCount;
} SAM_USER_FIXED_DATA, *PSAM_USER_FIXED_DATA;
/* database.c */
NTSTATUS

View file

@ -223,11 +223,18 @@ SampCreateUserAccount(HKEY hDomainKey,
LPCWSTR lpAccountName,
ULONG ulRelativeId)
{
SAM_USER_FIXED_DATA FixedUserData;
DWORD dwDisposition;
WCHAR szAccountKeyName[32];
HKEY hAccountKey = NULL;
HKEY hNamesKey = NULL;
/* Initialize fixed user data */
memset(&FixedUserData, 0, sizeof(SAM_USER_FIXED_DATA));
FixedUserData.Version = 1;
FixedUserData.UserId = ulRelativeId;
swprintf(szAccountKeyName, L"Users\\%08lX", ulRelativeId);
if (!RegCreateKeyExW(hDomainKey,
@ -240,6 +247,13 @@ SampCreateUserAccount(HKEY hDomainKey,
&hAccountKey,
&dwDisposition))
{
RegSetValueEx(hAccountKey,
L"F",
0,
REG_BINARY,
(LPVOID)&FixedUserData,
sizeof(SAM_USER_FIXED_DATA));
RegSetValueEx(hAccountKey,
L"Name",
0,