* PROGRAMMERS: Eric Kohl
*/
-/* INCLUDES ******************************************************************/
-
#include "samsrv.h"
-WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
-
/* GLOBALS *******************************************************************/
static SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
IN SECURITY_INFORMATION SecurityInformation,
OUT PSAMPR_SR_SECURITY_DESCRIPTOR *SecurityDescriptor)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PSAM_DB_OBJECT SamObject;
+ PSAMPR_SR_SECURITY_DESCRIPTOR SamSD = NULL;
+ PSECURITY_DESCRIPTOR SdBuffer = NULL;
+ ACCESS_MASK DesiredAccess = 0;
+ ULONG Length = 0;
+ NTSTATUS Status;
+
+ TRACE("(%p %lx %p)\n",
+ ObjectHandle, SecurityInformation, SecurityDescriptor);
+
+ *SecurityDescriptor = NULL;
+
+ RtlAcquireResourceShared(&SampResource,
+ TRUE);
+
+ if (SecurityInformation & (DACL_SECURITY_INFORMATION |
+ OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION))
+ DesiredAccess |= READ_CONTROL;
+
+ if (SecurityInformation & SACL_SECURITY_INFORMATION)
+ DesiredAccess |= ACCESS_SYSTEM_SECURITY;
+
+ /* Validate the server handle */
+ Status = SampValidateDbObject(ObjectHandle,
+ SamDbIgnoreObject,
+ DesiredAccess,
+ &SamObject);
+ if (!NT_SUCCESS(Status))
+ goto done;
+
+ SamSD = midl_user_allocate(sizeof(SAMPR_SR_SECURITY_DESCRIPTOR));
+ if (SamSD == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ Status = SampGetObjectAttribute(SamObject,
+ L"SecDesc",
+ NULL,
+ NULL,
+ &Length);
+ if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
+ {
+ TRACE("Status 0x%08lx\n", Status);
+ goto done;
+ }
+
+ TRACE("SD Length: %lu\n", Length);
+
+ SdBuffer = midl_user_allocate(Length);
+ if (SdBuffer == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ Status = SampGetObjectAttribute(SamObject,
+ L"SecDesc",
+ NULL,
+ SdBuffer,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("Status 0x%08lx\n", Status);
+ goto done;
+ }
+
+ /* FIXME: Use SecurityInformation to return only the requested information */
+
+ SamSD->Length = Length;
+ SamSD->SecurityDescriptor = SdBuffer;
+
+done:
+ RtlReleaseResource(&SampResource);
+
+ if (NT_SUCCESS(Status))
+ {
+ *SecurityDescriptor = SamSD;
+ }
+ else
+ {
+ if (SdBuffer != NULL)
+ midl_user_free(SdBuffer);
+
+ if (SamSD != NULL)
+ midl_user_free(SamSD);
+ }
+
+ return Status;
}
SAM_GROUP_FIXED_DATA FixedGroupData;
PSAM_DB_OBJECT DomainObject;
PSAM_DB_OBJECT GroupObject;
+ PSECURITY_DESCRIPTOR Sd = NULL;
+ ULONG SdSize = 0;
ULONG ulSize;
ULONG ulRid;
WCHAR szRid[9];
goto done;
}
+ /* Create the security descriptor */
+ Status = SampCreateGroupSD(&Sd,
+ &SdSize);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampCreateGroupSD failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
/* Get the fixed domain attributes */
ulSize = sizeof(SAM_DOMAIN_FIXED_DATA);
Status = SampGetObjectAttribute(DomainObject,
goto done;
}
+ /* Set the SecDesc attribute*/
+ Status = SampSetObjectAttribute(GroupObject,
+ L"SecDesc",
+ REG_BINARY,
+ Sd,
+ SdSize);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("failed with status 0x%08lx\n", Status);
+ goto done;
+ }
+
if (NT_SUCCESS(Status))
{
*GroupHandle = (SAMPR_HANDLE)GroupObject;
}
done:
+ if (Sd != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Sd);
+
RtlReleaseResource(&SampResource);
TRACE("returns with status 0x%08lx\n", Status);
ULONG ulSize;
ULONG ulRid;
WCHAR szRid[9];
+ PSECURITY_DESCRIPTOR Sd = NULL;
+ ULONG SdSize = 0;
+ PSID UserSid = NULL;
NTSTATUS Status;
TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
ulRid = FixedDomainData.NextRid;
FixedDomainData.NextRid++;
+ TRACE("RID: %lx\n", ulRid);
+
+ /* Create the user SID */
+ Status = SampCreateAccountSid(DomainObject,
+ ulRid,
+ &UserSid);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampCreateAccountSid failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* Create the security descriptor */
+ Status = SampCreateUserSD(UserSid,
+ &Sd,
+ &SdSize);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampCreateUserSD failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
/* Store the fixed domain attributes */
Status = SampSetObjectAttribute(DomainObject,
L"F",
goto done;
}
- TRACE("RID: %lx\n", ulRid);
-
/* Convert the RID into a string (hex) */
swprintf(szRid, L"%08lX", ulRid);
goto done;
}
- /* FIXME: Set SecDesc attribute*/
+ /* Set the PrivateData attribute */
+ Status = SampSetObjectAttributeString(UserObject,
+ L"PrivateData",
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("failed with status 0x%08lx\n", Status);
+ goto done;
+ }
+
+ /* Set the SecDesc attribute*/
+ Status = SampSetObjectAttribute(UserObject,
+ L"SecDesc",
+ REG_BINARY,
+ Sd,
+ SdSize);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("failed with status 0x%08lx\n", Status);
+ goto done;
+ }
if (NT_SUCCESS(Status))
{
}
done:
+ if (Sd != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Sd);
+
+ if (UserSid != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, UserSid);
+
RtlReleaseResource(&SampResource);
TRACE("returns with status 0x%08lx\n", Status);
SAM_DOMAIN_FIXED_DATA FixedDomainData;
PSAM_DB_OBJECT DomainObject;
PSAM_DB_OBJECT AliasObject;
+ PSECURITY_DESCRIPTOR Sd = NULL;
+ ULONG SdSize = 0;
ULONG ulSize;
ULONG ulRid;
WCHAR szRid[9];
goto done;
}
+ /* Create the security descriptor */
+ Status = SampCreateAliasSD(&Sd,
+ &SdSize);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampCreateAliasSD failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
/* Get the fixed domain attributes */
ulSize = sizeof(SAM_DOMAIN_FIXED_DATA);
Status = SampGetObjectAttribute(DomainObject,
goto done;
}
+ /* Set the SecDesc attribute*/
+ Status = SampSetObjectAttribute(AliasObject,
+ L"SecDesc",
+ REG_BINARY,
+ Sd,
+ SdSize);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("failed with status 0x%08lx\n", Status);
+ goto done;
+ }
+
if (NT_SUCCESS(Status))
{
*AliasHandle = (SAMPR_HANDLE)AliasObject;
}
done:
+ if (Sd != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Sd);
+
RtlReleaseResource(&SampResource);
TRACE("returns with status 0x%08lx\n", Status);
ULONG ValueCount;
ULONG DataLength;
ULONG i, j;
+ ULONG RidIndex;
NTSTATUS Status;
WCHAR NameBuffer[9];
goto done;
}
+ RidIndex = 0;
for (i = 0; i < SidArray->Count; i++)
{
ConvertSidToStringSid(SidArray->Sids[i].SidPointer, &MemberSidString);
NULL);
if (NT_SUCCESS(Status))
{
- RidArray[j] = wcstoul(NameBuffer, NULL, 16);
+ /* FIXME: Do not return each RID more than once. */
+ RidArray[RidIndex] = wcstoul(NameBuffer, NULL, 16);
+ RidIndex++;
}
}
}
}
done:
- SampRegCloseKey(&MembersKeyHandle);
SampRegCloseKey(&MembersKeyHandle);
SampRegCloseKey(&AliasesKeyHandle);
}
/* Allocate the names array */
- Names->Element = midl_user_allocate(Count * sizeof(ULONG));
+ Names->Element = midl_user_allocate(Count * sizeof(*Names->Element));
if (Names->Element == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
/* Allocate the use array */
- Use->Element = midl_user_allocate(Count * sizeof(ULONG));
+ Use->Element = midl_user_allocate(Count * sizeof(*Use->Element));
if (Use->Element == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
- /* FIXME: Remove all members from the alias */
+ /* Remove all members from the alias */
+ Status = SampRemoveAllMembersFromAlias(AliasObject);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampRemoveAllMembersFromAlias() failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
/* Delete the alias from the database */
Status = SampDeleteAccountDbObject(AliasObject);
OUT PSAMPR_PSID_ARRAY_OUT Members)
{
PSAM_DB_OBJECT AliasObject;
- HANDLE MembersKeyHandle = NULL;
PSAMPR_SID_INFORMATION MemberArray = NULL;
- ULONG ValueCount = 0;
- ULONG DataLength;
+ ULONG MemberCount = 0;
ULONG Index;
NTSTATUS Status;
goto done;
}
- /* Open the members key of the alias objct */
- Status = SampRegOpenKey(AliasObject->KeyHandle,
- L"Members",
- KEY_READ,
- &MembersKeyHandle);
- if (!NT_SUCCESS(Status))
- {
- ERR("SampRegOpenKey failed with status 0x%08lx\n", Status);
- goto done;
- }
-
- /* Get the number of members */
- Status = SampRegQueryKeyInfo(MembersKeyHandle,
- NULL,
- &ValueCount);
- if (!NT_SUCCESS(Status))
- {
- ERR("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status);
- goto done;
- }
-
- /* Allocate the member array */
- MemberArray = midl_user_allocate(ValueCount * sizeof(SAMPR_SID_INFORMATION));
- if (MemberArray == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto done;
- }
-
- /* Enumerate the members */
- Index = 0;
- while (TRUE)
- {
- /* Get the size of the next SID */
- DataLength = 0;
- Status = SampRegEnumerateValue(MembersKeyHandle,
- Index,
- NULL,
- NULL,
- NULL,
- NULL,
- &DataLength);
- if (!NT_SUCCESS(Status))
- {
- if (Status == STATUS_NO_MORE_ENTRIES)
- Status = STATUS_SUCCESS;
- break;
- }
-
- /* Allocate a buffer for the SID */
- MemberArray[Index].SidPointer = midl_user_allocate(DataLength);
- if (MemberArray[Index].SidPointer == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto done;
- }
-
- /* Read the SID into the buffer */
- Status = SampRegEnumerateValue(MembersKeyHandle,
- Index,
- NULL,
- NULL,
- NULL,
- (PVOID)MemberArray[Index].SidPointer,
- &DataLength);
- if (!NT_SUCCESS(Status))
- {
- goto done;
- }
-
- Index++;
- }
+ Status = SampGetMembersInAlias(AliasObject,
+ &MemberCount,
+ &MemberArray);
/* Return the number of members and the member array */
if (NT_SUCCESS(Status))
{
- Members->Count = ValueCount;
+ Members->Count = MemberCount;
Members->Sids = MemberArray;
}
{
if (MemberArray != NULL)
{
- for (Index = 0; Index < ValueCount; Index++)
+ for (Index = 0; Index < MemberCount; Index++)
{
if (MemberArray[Index].SidPointer != NULL)
midl_user_free(MemberArray[Index].SidPointer);
}
}
- /* Close the members key */
- SampRegCloseKey(&MembersKeyHandle);
-
RtlReleaseResource(&SampResource);
return Status;
goto done;
}
- /* FIXME: Remove the user from all groups */
+ /* Remove the user from all groups */
+ Status = SampRemoveUserFromAllGroups(UserObject);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampRemoveUserFromAllGroups() failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
- /* FIXME: Remove the user from all aliases */
+ /* Remove the user from all aliases */
+ Status = SampRemoveUserFromAllAliases(UserObject);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampRemoveUserFromAllAliases() failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
/* Delete the user from the database */
Status = SampDeleteAccountDbObject(UserObject);
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
+ InfoBuffer->Internal1.LmPasswordPresent = FALSE;
+ InfoBuffer->Internal1.NtPasswordPresent = FALSE;
+
/* Get the NT password */
Length = 0;
SampGetObjectAttribute(UserObject,
&Length);
if (!NT_SUCCESS(Status))
goto done;
+
+ if (memcmp(&InfoBuffer->Internal1.EncryptedNtOwfPassword,
+ &EmptyNtHash,
+ sizeof(ENCRYPTED_NT_OWF_PASSWORD)))
+ InfoBuffer->Internal1.NtPasswordPresent = TRUE;
}
- InfoBuffer->Internal1.NtPasswordPresent = (Length == sizeof(ENCRYPTED_NT_OWF_PASSWORD));
/* Get the LM password */
Length = 0;
&Length);
if (!NT_SUCCESS(Status))
goto done;
- }
- InfoBuffer->Internal1.LmPasswordPresent = (Length == sizeof(ENCRYPTED_LM_OWF_PASSWORD));
+ if (memcmp(&InfoBuffer->Internal1.EncryptedLmOwfPassword,
+ &EmptyLmHash,
+ sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
+ InfoBuffer->Internal1.LmPasswordPresent = TRUE;
+ }
InfoBuffer->Internal1.PasswordExpired = FALSE;
if (!NT_SUCCESS(Status))
goto done;
- if (UserObject->Access & USER_READ_GENERAL)
+ /* Set the fields to be returned */
+ if (UserObject->Trusted)
+ {
+ InfoBuffer->All.WhichFields = USER_ALL_READ_GENERAL_MASK |
+ USER_ALL_READ_LOGON_MASK |
+ USER_ALL_READ_ACCOUNT_MASK |
+ USER_ALL_READ_PREFERENCES_MASK |
+ USER_ALL_READ_TRUSTED_MASK;
+ }
+ else
+ {
+ InfoBuffer->All.WhichFields = 0;
+
+ if (UserObject->Access & USER_READ_GENERAL)
+ InfoBuffer->All.WhichFields |= USER_ALL_READ_GENERAL_MASK;
+
+ if (UserObject->Access & USER_READ_LOGON)
+ InfoBuffer->All.WhichFields |= USER_ALL_READ_LOGON_MASK;
+
+ if (UserObject->Access & USER_READ_ACCOUNT)
+ InfoBuffer->All.WhichFields |= USER_ALL_READ_ACCOUNT_MASK;
+
+ if (UserObject->Access & USER_READ_PREFERENCES)
+ InfoBuffer->All.WhichFields |= USER_ALL_READ_PREFERENCES_MASK;
+ }
+
+ /* Fail, if no fields are to be returned */
+ if (InfoBuffer->All.WhichFields == 0)
+ {
+ Status = STATUS_ACCESS_DENIED;
+ goto done;
+ }
+
+ /* Get the UserName attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_USERNAME)
{
- /* Get the Name string */
Status = SampGetObjectAttributeString(UserObject,
L"Name",
&InfoBuffer->All.UserName);
TRACE("Status 0x%08lx\n", Status);
goto done;
}
+ }
- /* Get the FullName string */
+ /* Get the FullName attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_FULLNAME)
+ {
Status = SampGetObjectAttributeString(UserObject,
L"FullName",
&InfoBuffer->All.FullName);
TRACE("Status 0x%08lx\n", Status);
goto done;
}
+ }
- /* Get the user ID*/
+ /* Get the UserId attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_USERID)
+ {
InfoBuffer->All.UserId = FixedData.UserId;
+ }
- /* Get the primary group ID */
+ /* Get the PrimaryGroupId attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_PRIMARYGROUPID)
+ {
InfoBuffer->All.PrimaryGroupId = FixedData.PrimaryGroupId;
+ }
- /* Get the AdminComment string */
+ /* Get the AdminComment attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_ADMINCOMMENT)
+ {
Status = SampGetObjectAttributeString(UserObject,
L"AdminComment",
&InfoBuffer->All.AdminComment);
TRACE("Status 0x%08lx\n", Status);
goto done;
}
+ }
- /* Get the UserComment string */
+ /* Get the UserComment attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_USERCOMMENT)
+ {
Status = SampGetObjectAttributeString(UserObject,
L"UserComment",
&InfoBuffer->All.UserComment);
TRACE("Status 0x%08lx\n", Status);
goto done;
}
-
- InfoBuffer->All.WhichFields |= USER_ALL_READ_GENERAL_MASK;
-// USER_ALL_USERNAME |
-// USER_ALL_FULLNAME |
-// USER_ALL_USERID |
-// USER_ALL_PRIMARYGROUPID |
-// USER_ALL_ADMINCOMMENT |
-// USER_ALL_USERCOMMENT;
}
- if (UserObject->Access & USER_READ_LOGON)
+ /* Get the HomeDirectory attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_HOMEDIRECTORY)
{
- /* Get the HomeDirectory string */
Status = SampGetObjectAttributeString(UserObject,
L"HomeDirectory",
&InfoBuffer->All.HomeDirectory);
TRACE("Status 0x%08lx\n", Status);
goto done;
}
+ }
- /* Get the HomeDirectoryDrive string */
+ /* Get the HomeDirectoryDrive attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_HOMEDIRECTORYDRIVE)
+ {
Status = SampGetObjectAttributeString(UserObject,
L"HomeDirectoryDrive",
&InfoBuffer->Home.HomeDirectoryDrive);
TRACE("Status 0x%08lx\n", Status);
goto done;
}
+ }
- /* Get the ScriptPath string */
+ /* Get the ScriptPath attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_SCRIPTPATH)
+ {
Status = SampGetObjectAttributeString(UserObject,
L"ScriptPath",
&InfoBuffer->All.ScriptPath);
TRACE("Status 0x%08lx\n", Status);
goto done;
}
+ }
- /* Get the ProfilePath string */
+ /* Get the ProfilePath attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_PROFILEPATH)
+ {
Status = SampGetObjectAttributeString(UserObject,
L"ProfilePath",
&InfoBuffer->All.ProfilePath);
TRACE("Status 0x%08lx\n", Status);
goto done;
}
+ }
- /* Get the WorkStations string */
+ /* Get the WorkStations attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_WORKSTATIONS)
+ {
Status = SampGetObjectAttributeString(UserObject,
L"WorkStations",
&InfoBuffer->All.WorkStations);
TRACE("Status 0x%08lx\n", Status);
goto done;
}
+ }
+
+ /* Get the LastLogon attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_LASTLOGON)
+ {
+ InfoBuffer->All.LastLogon.LowPart = FixedData.LastLogon.LowPart;
+ InfoBuffer->All.LastLogon.HighPart = FixedData.LastLogon.HighPart;
+ }
- /* Get the LogonHours attribute */
+ /* Get the LastLogoff attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_LASTLOGOFF)
+ {
+ InfoBuffer->All.LastLogoff.LowPart = FixedData.LastLogoff.LowPart;
+ InfoBuffer->All.LastLogoff.HighPart = FixedData.LastLogoff.HighPart;
+ }
+
+ /* Get the LogonHours attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_LOGONHOURS)
+ {
Status = SampGetLogonHoursAttrbute(UserObject,
&InfoBuffer->All.LogonHours);
if (!NT_SUCCESS(Status))
TRACE("Status 0x%08lx\n", Status);
goto done;
}
+ }
- InfoBuffer->All.LastLogon.LowPart = FixedData.LastLogon.LowPart;
- InfoBuffer->All.LastLogon.HighPart = FixedData.LastLogon.HighPart;
-
- InfoBuffer->All.LastLogoff.LowPart = FixedData.LastLogoff.LowPart;
- InfoBuffer->All.LastLogoff.HighPart = FixedData.LastLogoff.HighPart;
-
+ /* Get the BadPasswordCount attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_BADPASSWORDCOUNT)
+ {
InfoBuffer->All.BadPasswordCount = FixedData.BadPasswordCount;
+ }
+ /* Get the LogonCount attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_LOGONCOUNT)
+ {
InfoBuffer->All.LogonCount = FixedData.LogonCount;
+ }
+ /* Get the PasswordCanChange attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_PASSWORDCANCHANGE)
+ {
PasswordCanChange = SampAddRelativeTimeToTime(FixedData.PasswordLastSet,
DomainFixedData.MinPasswordAge);
InfoBuffer->All.PasswordCanChange.LowPart = PasswordCanChange.LowPart;
InfoBuffer->All.PasswordCanChange.HighPart = PasswordCanChange.HighPart;
+ }
+ /* Get the PasswordMustChange attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_PASSWORDMUSTCHANGE)
+ {
PasswordMustChange = SampAddRelativeTimeToTime(FixedData.PasswordLastSet,
DomainFixedData.MaxPasswordAge);
InfoBuffer->All.PasswordMustChange.LowPart = PasswordMustChange.LowPart;
InfoBuffer->All.PasswordMustChange.HighPart = PasswordMustChange.HighPart;
+ }
- InfoBuffer->All. WhichFields |= USER_ALL_READ_LOGON_MASK;
-/*
- USER_ALL_HOMEDIRECTORY |
- USER_ALL_HOMEDIRECTORYDRIVE |
- USER_ALL_SCRIPTPATH |
- USER_ALL_PROFILEPATH |
- USER_ALL_WORKSTATIONS |
- USER_ALL_LASTLOGON |
- USER_ALL_LASTLOGOFF |
- USER_ALL_LOGONHOURS |
- USER_ALL_BADPASSWORDCOUNT |
- USER_ALL_LOGONCOUNT;
- USER_ALL_PASSWORDCANCHANGE |
- USER_ALL_PASSWORDMUSTCHANGE;
-*/
- }
-
- if (UserObject->Access & USER_READ_ACCOUNT)
+ /* Get the PasswordLastSet attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_PASSWORDLASTSET)
{
InfoBuffer->All.PasswordLastSet.LowPart = FixedData.PasswordLastSet.LowPart;
InfoBuffer->All.PasswordLastSet.HighPart = FixedData.PasswordLastSet.HighPart;
+ }
+ /* Get the AccountExpires attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_ACCOUNTEXPIRES)
+ {
InfoBuffer->All.AccountExpires.LowPart = FixedData.AccountExpires.LowPart;
InfoBuffer->All.AccountExpires.HighPart = FixedData.AccountExpires.HighPart;
+ }
+ /* Get the UserAccountControl attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_USERACCOUNTCONTROL)
+ {
InfoBuffer->All.UserAccountControl = FixedData.UserAccountControl;
+ }
- /* Get the Parameters string */
+ /* Get the Parameters attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_PARAMETERS)
+ {
Status = SampGetObjectAttributeString(UserObject,
L"Parameters",
&InfoBuffer->All.Parameters);
TRACE("Status 0x%08lx\n", Status);
goto done;
}
-
- InfoBuffer->All. WhichFields |= USER_ALL_READ_ACCOUNT_MASK;
-// USER_ALL_PASSWORDLASTSET |
-// USER_ALL_ACCOUNTEXPIRES |
-// USER_ALL_USERACCOUNTCONTROL |
-// USER_ALL_PARAMETERS;
}
- if (UserObject->Access & USER_READ_PREFERENCES)
+ /* Get the CountryCode attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_COUNTRYCODE)
{
InfoBuffer->All.CountryCode = FixedData.CountryCode;
+ }
+ /* Get the CodePage attribute */
+ if (InfoBuffer->All.WhichFields & USER_ALL_CODEPAGE)
+ {
InfoBuffer->All.CodePage = FixedData.CodePage;
+ }
+
+ /* Get the LmPassword and NtPassword attributes */
+ if (InfoBuffer->All.WhichFields & (USER_ALL_NTPASSWORDPRESENT | USER_ALL_LMPASSWORDPRESENT))
+ {
+ InfoBuffer->All.LmPasswordPresent = FALSE;
+ InfoBuffer->All.NtPasswordPresent = FALSE;
+
+ /* Get the NT password */
+ Length = 0;
+ SampGetObjectAttribute(UserObject,
+ L"NTPwd",
+ NULL,
+ NULL,
+ &Length);
+
+ if (Length == sizeof(ENCRYPTED_NT_OWF_PASSWORD))
+ {
+ InfoBuffer->All.NtOwfPassword.Buffer = midl_user_allocate(sizeof(ENCRYPTED_NT_OWF_PASSWORD));
+ if (InfoBuffer->All.NtOwfPassword.Buffer == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ InfoBuffer->All.NtOwfPassword.Length = sizeof(ENCRYPTED_NT_OWF_PASSWORD);
+ InfoBuffer->All.NtOwfPassword.MaximumLength = sizeof(ENCRYPTED_NT_OWF_PASSWORD);
+
+ Status = SampGetObjectAttribute(UserObject,
+ L"NTPwd",
+ NULL,
+ (PVOID)InfoBuffer->All.NtOwfPassword.Buffer,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ goto done;
+
+ if (memcmp(InfoBuffer->All.NtOwfPassword.Buffer,
+ &EmptyNtHash,
+ sizeof(ENCRYPTED_NT_OWF_PASSWORD)))
+ InfoBuffer->All.NtPasswordPresent = TRUE;
+ }
+
+ /* Get the LM password */
+ Length = 0;
+ SampGetObjectAttribute(UserObject,
+ L"LMPwd",
+ NULL,
+ NULL,
+ &Length);
+
+ if (Length == sizeof(ENCRYPTED_LM_OWF_PASSWORD))
+ {
+ InfoBuffer->All.LmOwfPassword.Buffer = midl_user_allocate(sizeof(ENCRYPTED_LM_OWF_PASSWORD));
+ if (InfoBuffer->All.LmOwfPassword.Buffer == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ InfoBuffer->All.LmOwfPassword.Length = sizeof(ENCRYPTED_LM_OWF_PASSWORD);
+ InfoBuffer->All.LmOwfPassword.MaximumLength = sizeof(ENCRYPTED_LM_OWF_PASSWORD);
+
+ Status = SampGetObjectAttribute(UserObject,
+ L"LMPwd",
+ NULL,
+ (PVOID)InfoBuffer->All.LmOwfPassword.Buffer,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ goto done;
+
+ if (memcmp(InfoBuffer->All.LmOwfPassword.Buffer,
+ &EmptyLmHash,
+ sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
+ InfoBuffer->All.LmPasswordPresent = TRUE;
+ }
+ }
- InfoBuffer->All. WhichFields |= USER_ALL_READ_PREFERENCES_MASK;
-// USER_ALL_COUNTRYCODE |
-// USER_ALL_CODEPAGE;
+ if (InfoBuffer->All.WhichFields & USER_ALL_PRIVATEDATA)
+ {
+ Status = SampGetObjectAttributeString(UserObject,
+ L"PrivateData",
+ &InfoBuffer->All.PrivateData);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("Status 0x%08lx\n", Status);
+ goto done;
+ }
+ }
+
+ if (InfoBuffer->All.WhichFields & USER_ALL_PASSWORDEXPIRED)
+ {
+ /* FIXME */
+ }
+
+ if (InfoBuffer->All.WhichFields & USER_ALL_SECURITYDESCRIPTOR)
+ {
+ Length = 0;
+ SampGetObjectAttribute(UserObject,
+ L"SecDesc",
+ NULL,
+ NULL,
+ &Length);
+
+ if (Length > 0)
+ {
+ InfoBuffer->All.SecurityDescriptor.SecurityDescriptor = midl_user_allocate(Length);
+ if (InfoBuffer->All.SecurityDescriptor.SecurityDescriptor == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ InfoBuffer->All.SecurityDescriptor.Length = Length;
+
+ Status = SampGetObjectAttribute(UserObject,
+ L"SecDesc",
+ NULL,
+ (PVOID)InfoBuffer->All.SecurityDescriptor.SecurityDescriptor,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ goto done;
+ }
}
*Buffer = InfoBuffer;
if (InfoBuffer->All.Parameters.Buffer != NULL)
midl_user_free(InfoBuffer->All.Parameters.Buffer);
+ if (InfoBuffer->All.LmOwfPassword.Buffer != NULL)
+ midl_user_free(InfoBuffer->All.LmOwfPassword.Buffer);
+
+ if (InfoBuffer->All.NtOwfPassword.Buffer != NULL)
+ midl_user_free(InfoBuffer->All.NtOwfPassword.Buffer);
+
+ if (InfoBuffer->All.PrivateData.Buffer != NULL)
+ midl_user_free(InfoBuffer->All.PrivateData.Buffer);
+
+ if (InfoBuffer->All.SecurityDescriptor.SecurityDescriptor != NULL)
+ midl_user_free(InfoBuffer->All.SecurityDescriptor.SecurityDescriptor);
+
midl_user_free(InfoBuffer);
}
}
if (Buffer->Internal1.PasswordExpired)
{
- /* The pasword was last set ages ago */
+ /* The password was last set ages ago */
FixedData.PasswordLastSet.LowPart = 0;
FixedData.PasswordLastSet.HighPart = 0;
}
else
{
- /* The pasword was last set right now */
+ /* The password was last set right now */
Status = NtQuerySystemTime(&FixedData.PasswordLastSet);
if (!NT_SUCCESS(Status))
goto done;
WriteFixedData = TRUE;
}
+ if (WhichFields & USER_ALL_PRIVATEDATA)
+ {
+ Status = SampSetObjectAttributeString(UserObject,
+ L"PrivateData",
+ &Buffer->All.PrivateData);
+ if (!NT_SUCCESS(Status))
+ goto done;
+ }
+
if (WhichFields & USER_ALL_PASSWORDEXPIRED)
{
if (Buffer->All.PasswordExpired)
WriteFixedData = TRUE;
}
+ if (WhichFields & USER_ALL_SECURITYDESCRIPTOR)
+ {
+ Status = SampSetObjectAttribute(UserObject,
+ L"SecDesc",
+ REG_BINARY,
+ Buffer->All.SecurityDescriptor.SecurityDescriptor,
+ Buffer->All.SecurityDescriptor.Length);
+ }
+
if (WriteFixedData == TRUE)
{
Status = SampSetObjectAttribute(UserObject,
{
ENCRYPTED_LM_OWF_PASSWORD StoredLmPassword;
ENCRYPTED_NT_OWF_PASSWORD StoredNtPassword;
- PENCRYPTED_LM_OWF_PASSWORD OldLmPassword;
- PENCRYPTED_LM_OWF_PASSWORD NewLmPassword;
- PENCRYPTED_NT_OWF_PASSWORD OldNtPassword;
- PENCRYPTED_NT_OWF_PASSWORD NewNtPassword;
+ ENCRYPTED_LM_OWF_PASSWORD OldLmPassword;
+ ENCRYPTED_LM_OWF_PASSWORD NewLmPassword;
+ ENCRYPTED_NT_OWF_PASSWORD OldNtPassword;
+ ENCRYPTED_NT_OWF_PASSWORD NewNtPassword;
BOOLEAN StoredLmPresent = FALSE;
BOOLEAN StoredNtPresent = FALSE;
BOOLEAN StoredLmEmpty = TRUE;
if (!NT_SUCCESS(Status))
{
TRACE("SampGetObjectAttribute failed to retrieve the fixed domain data (Status 0x%08lx)\n", Status);
- return Status;
+ goto done;
}
if (DomainFixedData.MinPasswordAge.QuadPart > 0)
{
if (SystemTime.QuadPart < (UserFixedData.PasswordLastSet.QuadPart + DomainFixedData.MinPasswordAge.QuadPart))
- return STATUS_ACCOUNT_RESTRICTION;
+ {
+ Status = STATUS_ACCOUNT_RESTRICTION;
+ goto done;
+ }
+ }
+ }
+
+ /* Decrypt the LM passwords, if present */
+ if (LmPresent)
+ {
+ Status = SystemFunction013((const BYTE *)NewLmEncryptedWithOldLm,
+ (const BYTE *)&StoredLmPassword,
+ (LPBYTE)&NewLmPassword);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ Status = SystemFunction013((const BYTE *)OldLmEncryptedWithNewLm,
+ (const BYTE *)&NewLmPassword,
+ (LPBYTE)&OldLmPassword);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status);
+ goto done;
}
}
- /* FIXME: Decrypt passwords */
- OldLmPassword = OldLmEncryptedWithNewLm;
- NewLmPassword = NewLmEncryptedWithOldLm;
- OldNtPassword = OldNtEncryptedWithNewNt;
- NewNtPassword = NewNtEncryptedWithOldNt;
+ /* Decrypt the NT passwords, if present */
+ if (NtPresent)
+ {
+ Status = SystemFunction013((const BYTE *)NewNtEncryptedWithOldNt,
+ (const BYTE *)&StoredNtPassword,
+ (LPBYTE)&NewNtPassword);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ Status = SystemFunction013((const BYTE *)OldNtEncryptedWithNewNt,
+ (const BYTE *)&NewNtPassword,
+ (LPBYTE)&OldNtPassword);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+ }
/* Check if the old passwords match the stored ones */
if (NtPresent)
if (LmPresent)
{
if (!RtlEqualMemory(&StoredLmPassword,
- OldLmPassword,
+ &OldLmPassword,
sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
{
TRACE("Old LM Password does not match!\n");
else
{
if (!RtlEqualMemory(&StoredNtPassword,
- OldNtPassword,
+ &OldNtPassword,
sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
{
TRACE("Old NT Password does not match!\n");
else
{
if (!RtlEqualMemory(&StoredNtPassword,
- OldNtPassword,
+ &OldNtPassword,
sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
{
TRACE("Old NT Password does not match!\n");
if (LmPresent)
{
if (!RtlEqualMemory(&StoredLmPassword,
- OldLmPassword,
+ &OldLmPassword,
sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
{
TRACE("Old LM Password does not match!\n");
if (NT_SUCCESS(Status))
{
Status = SampSetUserPassword(UserObject,
- NewNtPassword,
+ &NewNtPassword,
NtPresent,
- NewLmPassword,
+ &NewLmPassword,
LmPresent);
if (NT_SUCCESS(Status))
{
ULONG ulSize;
ULONG ulRid;
WCHAR szRid[9];
+ PSECURITY_DESCRIPTOR Sd = NULL;
+ ULONG SdSize = 0;
+ PSID UserSid = NULL;
NTSTATUS Status;
TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
ulRid = FixedDomainData.NextRid;
FixedDomainData.NextRid++;
+ TRACE("RID: %lx\n", ulRid);
+
+ /* Create the user SID */
+ Status = SampCreateAccountSid(DomainObject,
+ ulRid,
+ &UserSid);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampCreateAccountSid failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
+ /* Create the security descriptor */
+ Status = SampCreateUserSD(UserSid,
+ &Sd,
+ &SdSize);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SampCreateUserSD failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
/* Store the fixed domain attributes */
Status = SampSetObjectAttribute(DomainObject,
L"F",
goto done;
}
- TRACE("RID: %lx\n", ulRid);
-
/* Convert the RID into a string (hex) */
swprintf(szRid, L"%08lX", ulRid);
goto done;
}
- /* FIXME: Set SecDesc attribute*/
+ /* Set the PrivateData attribute */
+ Status = SampSetObjectAttributeString(UserObject,
+ L"PrivateData",
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("failed with status 0x%08lx\n", Status);
+ goto done;
+ }
+
+ /* Set the SecDesc attribute*/
+ Status = SampSetObjectAttribute(UserObject,
+ L"SecDesc",
+ REG_BINARY,
+ Sd,
+ SdSize);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("failed with status 0x%08lx\n", Status);
+ goto done;
+ }
if (NT_SUCCESS(Status))
{
}
done:
+ if (Sd != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Sd);
+
+ if (UserSid != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, UserSid);
+
RtlReleaseResource(&SampResource);
TRACE("returns with status 0x%08lx\n", Status);