* 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);
EnumBuffer->Buffer[i].RelativeId = Rid;
EnumBuffer->Buffer[i].Name.Length = (USHORT)NameLength;
- EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(DataLength + sizeof(UNICODE_NULL));
+ EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(NameLength + sizeof(UNICODE_NULL));
/* FIXME: Disabled because of bugs in widl and rpcrt4 */
#if 0
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);
EnumBuffer->Buffer[i].RelativeId = Rid;
EnumBuffer->Buffer[i].Name.Length = (USHORT)NameLength;
- EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(DataLength + sizeof(UNICODE_NULL));
+ EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(NameLength + sizeof(UNICODE_NULL));
/* FIXME: Disabled because of bugs in widl and rpcrt4 */
#if 0
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);
EnumBuffer->Buffer[i].RelativeId = Rid;
EnumBuffer->Buffer[i].Name.Length = (USHORT)NameLength;
- EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(DataLength + sizeof(UNICODE_NULL));
+ EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(NameLength + sizeof(UNICODE_NULL));
/* FIXME: Disabled because of bugs in widl and rpcrt4 */
#if 0
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 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->All.WhichFields & USER_ALL_PRIVATEDATA)
{
- /* FIXME */
+ 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)
if (InfoBuffer->All.WhichFields & USER_ALL_SECURITYDESCRIPTOR)
{
- /* FIXME */
+ 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.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;
LARGE_INTEGER SystemTime;
NTSTATUS Status;
+ DBG_UNREFERENCED_LOCAL_VARIABLE(StoredLmPresent);
+ DBG_UNREFERENCED_LOCAL_VARIABLE(StoredNtPresent);
+ DBG_UNREFERENCED_LOCAL_VARIABLE(StoredLmEmpty);
+
TRACE("(%p %u %p %p %u %p %p %u %p %u %p)\n",
UserHandle, LmPresent, OldLmEncryptedWithNewLm, NewLmEncryptedWithOldLm,
NtPresent, OldNtEncryptedWithNewNt, NewNtEncryptedWithOldNt, NtCrossEncryptionPresent,
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;
+ }
}
}
- /* FIXME: Decrypt passwords */
- OldLmPassword = OldLmEncryptedWithNewLm;
- NewLmPassword = NewLmEncryptedWithOldLm;
- OldNtPassword = OldNtEncryptedWithNewNt;
- NewNtPassword = NewNtEncryptedWithOldNt;
+ /* 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;
+ }
+ }
+
+ /* 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);