Create and set a security descriptor for new user account objects.

svn path=/trunk/; revision=60750
This commit is contained in:
Eric Kohl 2013-10-26 09:09:31 +00:00
parent 52a74dbc90
commit c2691edfa1
5 changed files with 445 additions and 13 deletions

View file

@ -303,4 +303,55 @@ SampRemoveMemberFromAllAliases(IN PSAM_DB_OBJECT DomainObject,
return Status;
}
NTSTATUS
SampCreateAccountSid(IN PSAM_DB_OBJECT DomainObject,
IN ULONG ulRelativeId,
IN OUT PSID *AccountSid)
{
PSID DomainSid = NULL;
ULONG Length = 0;
NTSTATUS Status;
Status = SampGetObjectAttribute(DomainObject,
L"SID",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
TRACE("Length: %lu\n", Length);
DomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
if (DomainSid == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
Status = SampGetObjectAttribute(DomainObject,
L"SID",
NULL,
DomainSid,
&Length);
if (!NT_SUCCESS(Status))
{
TRACE("Status 0x%08lx\n", Status);
goto done;
}
*AccountSid = AppendRidToSid(DomainSid,
ulRelativeId);
done:
if (DomainSid != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
return Status;
}
/* EOF */

View file

@ -2174,6 +2174,9 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
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",
@ -2239,6 +2242,28 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
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",
@ -2251,8 +2276,6 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
goto done;
}
TRACE("RID: %lx\n", ulRid);
/* Convert the RID into a string (hex) */
swprintf(szRid, L"%08lX", ulRid);
@ -2505,7 +2528,17 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
goto done;
}
/* FIXME: Set SecDesc attribute*/
/* 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))
{
@ -2514,6 +2547,12 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
}
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);
@ -6871,7 +6910,6 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject,
if (InfoBuffer->All.WhichFields & USER_ALL_SECURITYDESCRIPTOR)
{
#if 0
Length = 0;
SampGetObjectAttribute(UserObject,
L"SecDesc",
@ -6898,7 +6936,6 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject,
if (!NT_SUCCESS(Status))
goto done;
}
#endif
}
*Buffer = InfoBuffer;
@ -7670,13 +7707,11 @@ SampSetUserAll(PSAM_DB_OBJECT UserObject,
if (WhichFields & USER_ALL_SECURITYDESCRIPTOR)
{
#if 0
Status = SampSetObjectAttribute(UserObject,
L"SecDesc",
REG_BINARY,
Buffer->All.SecurityDescriptor.SecurityDescriptor,
Buffer->All.SecurityDescriptor.Length);
#endif
}
if (WriteFixedData == TRUE)
@ -8523,6 +8558,9 @@ SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle,
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",
@ -8596,6 +8634,28 @@ SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle,
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",
@ -8608,8 +8668,6 @@ SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle,
goto done;
}
TRACE("RID: %lx\n", ulRid);
/* Convert the RID into a string (hex) */
swprintf(szRid, L"%08lX", ulRid);
@ -8861,7 +8919,17 @@ SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle,
goto done;
}
/* FIXME: Set SecDesc attribute*/
/* 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))
{
@ -8871,6 +8939,12 @@ SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle,
}
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);

View file

@ -230,6 +230,10 @@ NTSTATUS
SampRemoveMemberFromAllAliases(IN PSAM_DB_OBJECT DomainObject,
IN PRPC_SID MemberSid);
NTSTATUS
SampCreateAccountSid(IN PSAM_DB_OBJECT DomainObject,
IN ULONG ulRelativeId,
IN OUT PSID *AccountSid);
/* group.h */
@ -336,6 +340,10 @@ NTSTATUS
SampCreateGroupSD(OUT PSECURITY_DESCRIPTOR *GroupSd,
OUT PULONG Size);
NTSTATUS
SampCreateUserSD(IN PSID UserSid,
OUT PSECURITY_DESCRIPTOR *UserSd,
OUT PULONG Size);
/* setup.c */

View file

@ -1433,4 +1433,276 @@ done:
return Status;
}
NTSTATUS
SampCreateUserSD(IN PSID UserSid,
OUT PSECURITY_DESCRIPTOR *UserSd,
OUT PULONG Size)
{
PSECURITY_DESCRIPTOR AbsSD = NULL;
PSECURITY_DESCRIPTOR RelSD = NULL;
PSID EveryoneSid = NULL;
PSID AnonymousSid = NULL;
PSID AdministratorsSid = NULL;
PACL Dacl = NULL;
PACL Sacl = NULL;
ULONG DaclSize;
ULONG SaclSize;
ULONG RelSDSize = 0;
NTSTATUS Status = STATUS_SUCCESS;
/* Create the Everyone SID */
Status = RtlAllocateAndInitializeSid(&WorldAuthority,
1,
SECURITY_WORLD_RID,
0,
0,
0,
0,
0,
0,
0,
&EveryoneSid);
ASSERT(NT_SUCCESS(Status));
if (!NT_SUCCESS(Status))
goto done;
/* Create the Anonymous SID */
Status = RtlAllocateAndInitializeSid(&NtAuthority,
1,
SECURITY_ANONYMOUS_LOGON_RID,
0,
0,
0,
0,
0,
0,
0,
&AnonymousSid);
ASSERT(NT_SUCCESS(Status));
if (!NT_SUCCESS(Status))
goto done;
/* Create the Administrators SID */
Status = RtlAllocateAndInitializeSid(&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0,
0,
0,
0,
0,
0,
&AdministratorsSid);
ASSERT(NT_SUCCESS(Status));
if (!NT_SUCCESS(Status))
goto done;
/* Allocate a buffer for the absolute SD */
AbsSD = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(SECURITY_DESCRIPTOR));
if (AbsSD == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
ASSERT(Status == STATUS_SUCCESS);
goto done;
}
/* Create the absolute SD */
Status = RtlCreateSecurityDescriptor(AbsSD,
SECURITY_DESCRIPTOR_REVISION);
ASSERT(NT_SUCCESS(Status));
if (!NT_SUCCESS(Status))
goto done;
/* allocate and create the DACL */
DaclSize = sizeof(ACL) +
3 * sizeof(ACE) +
RtlLengthSid(EveryoneSid) +
RtlLengthSid(AdministratorsSid) +
RtlLengthSid(UserSid);
Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
DaclSize);
if (Dacl == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
ASSERT(Status == STATUS_SUCCESS);
goto done;
}
Status = RtlCreateAcl(Dacl,
DaclSize,
ACL_REVISION);
ASSERT(NT_SUCCESS(Status));
if (!NT_SUCCESS(Status))
goto done;
Status = RtlAddAccessAllowedAce(Dacl,
ACL_REVISION,
READ_CONTROL | USER_READ_GROUP_INFORMATION | USER_LIST_GROUPS |
USER_CHANGE_PASSWORD | USER_READ_ACCOUNT | USER_READ_LOGON |
USER_READ_PREFERENCES | USER_READ_GENERAL,
EveryoneSid);
ASSERT(NT_SUCCESS(Status));
if (!NT_SUCCESS(Status))
goto done;
Status = RtlAddAccessAllowedAce(Dacl,
ACL_REVISION,
USER_ALL_ACCESS,
AdministratorsSid);
ASSERT(Status == STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
goto done;
Status = RtlAddAccessAllowedAce(Dacl,
ACL_REVISION,
READ_CONTROL | USER_CHANGE_PASSWORD | USER_WRITE_PREFERENCES,
UserSid);
ASSERT(Status == STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
goto done;
/* Set the DACL */
Status = RtlSetDaclSecurityDescriptor(AbsSD,
TRUE,
Dacl,
FALSE);
ASSERT(Status == STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
goto done;
/* allocate and create the SACL */
SaclSize = sizeof(ACL) +
2 * sizeof(ACE) +
RtlLengthSid(EveryoneSid) +
RtlLengthSid(AnonymousSid);
Sacl = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
DaclSize);
if (Sacl == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
ASSERT(Status == STATUS_SUCCESS);
goto done;
}
Status = RtlCreateAcl(Sacl,
SaclSize,
ACL_REVISION);
ASSERT(Status == STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
goto done;
Status = RtlAddAuditAccessAce(Sacl,
ACL_REVISION,
ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE |
USER_CHANGE_PASSWORD | USER_WRITE_PREFERENCES,
EveryoneSid,
TRUE,
TRUE);
ASSERT(Status == STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
goto done;
Status = RtlAddAuditAccessAce(Sacl,
ACL_REVISION,
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
AnonymousSid,
TRUE,
TRUE);
ASSERT(Status == STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
goto done;
/* Set the SACL */
Status = RtlSetSaclSecurityDescriptor(AbsSD,
TRUE,
Sacl,
FALSE);
ASSERT(Status == STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
goto done;
/* Set the owner SID */
Status = RtlSetOwnerSecurityDescriptor(AbsSD,
AdministratorsSid,
FALSE);
ASSERT(Status == STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
goto done;
/* Set the group SID */
Status = RtlSetGroupSecurityDescriptor(AbsSD,
AdministratorsSid,
FALSE);
ASSERT(Status == STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
goto done;
/* Get the reqired buffer size for the self-relative SD */
Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
NULL,
&RelSDSize);
if (Status != STATUS_BUFFER_TOO_SMALL)
goto done;
/* Allocate a buffer for the self-relative SD */
RelSD = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
RelSDSize);
if (RelSD == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
ASSERT(Status == STATUS_SUCCESS);
goto done;
}
/* Convert the absolute SD to self-relative format */
Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
RelSD,
&RelSDSize);
if (Status == STATUS_BUFFER_TOO_SMALL)
{
ASSERT(Status == STATUS_SUCCESS);
goto done;
}
*UserSd = RelSD;
*Size = RelSDSize;
done:
if (!NT_SUCCESS(Status))
{
if (RelSD != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD);
}
if (EveryoneSid != NULL)
RtlFreeSid(EveryoneSid);
if (AnonymousSid != NULL)
RtlFreeSid(AnonymousSid);
if (AdministratorsSid != NULL)
RtlFreeSid(AdministratorsSid);
if (Dacl != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
if (Sacl != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl);
if (AbsSD != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD);
return Status;
}
/* EOF */

View file

@ -359,6 +359,7 @@ NTSTATUS
SampSetupCreateUserAccount(HANDLE hDomainKey,
LPCWSTR lpAccountName,
LPCWSTR lpComment,
PSID lpDomainSid,
ULONG ulRelativeId,
ULONG UserAccountControl)
{
@ -369,8 +370,21 @@ SampSetupCreateUserAccount(HANDLE hDomainKey,
WCHAR szAccountKeyName[32];
HANDLE hAccountKey = NULL;
HANDLE hNamesKey = NULL;
PSECURITY_DESCRIPTOR Sd = NULL;
ULONG SdSize = 0;
PSID UserSid = NULL;
NTSTATUS Status;
UserSid = AppendRidToSid(lpDomainSid,
ulRelativeId);
/* Create the security descriptor */
Status = SampCreateUserSD(UserSid,
&Sd,
&SdSize);
if (!NT_SUCCESS(Status))
goto done;
/* Initialize fixed user data */
FixedUserData.Version = 1;
FixedUserData.Reserved = 0;
@ -558,9 +572,14 @@ SampSetupCreateUserAccount(HANDLE hDomainKey,
if (!NT_SUCCESS(Status))
goto done;
/* FIXME: Set SecDesc attribute*/
/* Set the SecDesc attribute*/
Status = SampRegSetValue(hAccountKey,
L"SecDesc",
REG_BINARY,
Sd,
SdSize);
if (!NT_SUCCESS(Status))
goto done;
Status = SampRegOpenKey(hDomainKey,
L"Users\\Names",
@ -578,6 +597,12 @@ SampSetupCreateUserAccount(HANDLE hDomainKey,
done:
SampRegCloseKey(&hNamesKey);
if (Sd != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Sd);
if (UserSid != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, UserSid);
if (hAccountKey != NULL)
{
SampRegCloseKey(&hAccountKey);
@ -1057,6 +1082,7 @@ SampInitializeSAM(VOID)
SampSetupCreateUserAccount(hAccountDomainKey,
szName,
szComment,
AccountDomainInfo->DomainSid,
DOMAIN_USER_RID_ADMIN,
USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT);
@ -1070,6 +1096,7 @@ SampInitializeSAM(VOID)
SampSetupCreateUserAccount(hAccountDomainKey,
szName,
szComment,
AccountDomainInfo->DomainSid,
DOMAIN_USER_RID_GUEST,
USER_ACCOUNT_DISABLED | USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT);