[LSASRV][MSV1_0]

- Add all groups, of which the user is a member, to the token group list.
- Remove the hard-coded administrators group and users group from the token group list.

This patch enables us to create ordinary user accounts which are not members of the administrator group and which do not have administrator privileges. Now we can start to test and fix the security components!

svn path=/trunk/; revision=61539
This commit is contained in:
Eric Kohl 2014-01-05 16:06:16 +00:00
parent 3ad827aa50
commit c3b566e4d8
4 changed files with 321 additions and 40 deletions

View file

@ -98,6 +98,60 @@ VOID
NTAPI
LsaIFree_LSAPR_PRIVILEGE_SET(IN PLSAPR_PRIVILEGE_SET Ptr);
typedef wchar_t *PSAMPR_SERVER_NAME;
typedef void *SAMPR_HANDLE;
typedef struct _SAMPR_ULONG_ARRAY
{
unsigned long Count;
unsigned long *Element;
} SAMPR_ULONG_ARRAY, *PSAMPR_ULONG_ARRAY;
typedef struct _SAMPR_SID_INFORMATION
{
PRPC_SID SidPointer;
} SAMPR_SID_INFORMATION, *PSAMPR_SID_INFORMATION;
typedef struct _SAMPR_PSID_ARRAY
{
unsigned long Count;
PSAMPR_SID_INFORMATION Sids;
} SAMPR_PSID_ARRAY, *PSAMPR_PSID_ARRAY;
NTSTATUS
NTAPI
SamIConnect(
PSAMPR_SERVER_NAME ServerName,
SAMPR_HANDLE *ServerHandle,
ACCESS_MASK DesiredAccess,
BOOLEAN Trusted);
VOID
NTAPI
SamIFree_SAMPR_ULONG_ARRAY(
PSAMPR_ULONG_ARRAY Ptr);
NTSTATUS
__stdcall
SamrCloseHandle(
SAMPR_HANDLE *SamHandle);
NTSTATUS
__stdcall
SamrOpenDomain(
SAMPR_HANDLE ServerHandle,
ACCESS_MASK DesiredAccess,
PRPC_SID DomainId,
SAMPR_HANDLE *DomainHandle);
NTSTATUS
__stdcall
SamrGetAliasMembership(
SAMPR_HANDLE DomainHandle,
PSAMPR_PSID_ARRAY SidArray,
PSAMPR_ULONG_ARRAY Membership);
/* GLOBALS *****************************************************************/
static LIST_ENTRY PackageListHead;
@ -857,6 +911,223 @@ LsapAddDefaultGroups(
}
static
NTSTATUS
LsapAppendSidToGroups(
IN PTOKEN_GROUPS *TokenGroups,
IN PSID DomainSid,
IN ULONG RelativeId)
{
PTOKEN_GROUPS Groups;
PSID Sid;
ULONG Length;
ULONG i;
Sid = LsapAppendRidToSid(DomainSid, RelativeId);
if (Sid == NULL)
{
ERR("Group SID creation failed!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
if (*TokenGroups == NULL)
{
Length = sizeof(TOKEN_GROUPS) +
(1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
if (Groups == NULL)
{
ERR("Group buffer allocation failed!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
Groups->GroupCount = 1;
Groups->Groups[0].Sid = Sid;
Groups->Groups[0].Attributes =
SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
*TokenGroups = Groups;
}
else
{
for (i = 0; i < (*TokenGroups)->GroupCount; i++)
{
if (RtlEqualSid((*TokenGroups)->Groups[i].Sid, Sid))
{
RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
return STATUS_SUCCESS;
}
}
Length = sizeof(TOKEN_GROUPS) +
((*TokenGroups)->GroupCount + 1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
if (Groups == NULL)
{
ERR("Group buffer allocation failed!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
Groups->GroupCount = (*TokenGroups)->GroupCount;
for (i = 0; i < (*TokenGroups)->GroupCount; i++)
{
Groups->Groups[i].Sid = (*TokenGroups)->Groups[i].Sid;
Groups->Groups[i].Attributes = (*TokenGroups)->Groups[i].Attributes;
}
Groups->Groups[Groups->GroupCount].Sid = Sid;
Groups->Groups[Groups->GroupCount].Attributes =
SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
Groups->GroupCount++;
RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenGroups);
*TokenGroups = Groups;
}
return STATUS_SUCCESS;
}
static
NTSTATUS
LsapAddSamGroups(
IN PVOID TokenInformation,
IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
{
PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
SAMPR_HANDLE ServerHandle = NULL;
SAMPR_HANDLE BuiltinDomainHandle = NULL;
SAMPR_HANDLE AccountDomainHandle = NULL;
SAMPR_PSID_ARRAY SidArray;
SAMPR_ULONG_ARRAY BuiltinMembership;
SAMPR_ULONG_ARRAY AccountMembership;
ULONG i;
NTSTATUS Status = STATUS_SUCCESS;
if (TokenInformationType != LsaTokenInformationV1)
return STATUS_SUCCESS;
TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
SidArray.Count = TokenInfo1->Groups->GroupCount + 1;
SidArray.Sids = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
(TokenInfo1->Groups->GroupCount + 1) * sizeof(PRPC_SID));
if (SidArray.Sids == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
SidArray.Sids[0].SidPointer = TokenInfo1->User.User.Sid;
for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
SidArray.Sids[i + 1].SidPointer = TokenInfo1->Groups->Groups[i].Sid;
Status = SamIConnect(NULL,
&ServerHandle,
SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
FALSE);
if (!NT_SUCCESS(Status))
{
TRACE("SamIConnect failed (Status %08lx)\n", Status);
goto done;
}
Status = SamrOpenDomain(ServerHandle,
DOMAIN_GET_ALIAS_MEMBERSHIP,
BuiltinDomainSid,
&BuiltinDomainHandle);
if (!NT_SUCCESS(Status))
{
TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
goto done;
}
Status = SamrOpenDomain(ServerHandle,
DOMAIN_GET_ALIAS_MEMBERSHIP,
AccountDomainSid,
&AccountDomainHandle);
if (!NT_SUCCESS(Status))
{
TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
goto done;
}
BuiltinMembership.Element = NULL;
Status = SamrGetAliasMembership(BuiltinDomainHandle,
&SidArray,
&BuiltinMembership);
if (!NT_SUCCESS(Status))
{
TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
goto done;
}
AccountMembership.Element = NULL;
Status = SamrGetAliasMembership(AccountDomainHandle,
&SidArray,
&AccountMembership);
if (!NT_SUCCESS(Status))
{
TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
goto done;
}
TRACE("Builtin Memberships: %lu\n", BuiltinMembership.Count);
for (i = 0; i < BuiltinMembership.Count; i++)
{
TRACE("RID %lu: %lu (0x%lx)\n", i, BuiltinMembership.Element[i], BuiltinMembership.Element[i]);
Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
BuiltinDomainSid,
BuiltinMembership.Element[i]);
if (!NT_SUCCESS(Status))
{
TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
goto done;
}
}
TRACE("Account Memberships: %lu\n", AccountMembership.Count);
for (i = 0; i < AccountMembership.Count; i++)
{
TRACE("RID %lu: %lu (0x%lx)\n", i, AccountMembership.Element[i], AccountMembership.Element[i]);
Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
AccountDomainSid,
AccountMembership.Element[i]);
if (!NT_SUCCESS(Status))
{
TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
goto done;
}
}
done:
RtlFreeHeap(RtlGetProcessHeap(), 0, SidArray.Sids);
if (AccountMembership.Element != NULL)
SamIFree_SAMPR_ULONG_ARRAY(&AccountMembership);
if (BuiltinMembership.Element != NULL)
SamIFree_SAMPR_ULONG_ARRAY(&BuiltinMembership);
if (AccountDomainHandle != NULL)
SamrCloseHandle(&AccountDomainHandle);
if (BuiltinDomainHandle != NULL)
SamrCloseHandle(&BuiltinDomainHandle);
if (ServerHandle != NULL)
SamrCloseHandle(&ServerHandle);
// return Status;
return STATUS_SUCCESS;
}
static
NTSTATUS
LsapSetTokenOwner(
@ -1231,6 +1502,14 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
goto done;
}
Status = LsapAddSamGroups(TokenInformation,
TokenInformationType);
if (!NT_SUCCESS(Status))
{
ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status);
goto done;
}
Status = LsapSetTokenOwner(TokenInformation,
TokenInformationType);
if (!NT_SUCCESS(Status))

View file

@ -415,4 +415,9 @@ LsapLoadString(HINSTANCE hInstance,
LPWSTR lpBuffer,
INT nBufferMax);
PSID
LsapAppendRidToSid(
PSID SrcSid,
ULONG Rid);
/* EOF */

View file

@ -57,4 +57,40 @@ LsapLoadString(HINSTANCE hInstance,
return i;
}
PSID
LsapAppendRidToSid(
PSID SrcSid,
ULONG Rid)
{
ULONG Rids[8] = {0, 0, 0, 0, 0, 0, 0, 0};
UCHAR RidCount;
PSID DstSid;
ULONG i;
RidCount = *RtlSubAuthorityCountSid(SrcSid);
if (RidCount >= 8)
return NULL;
for (i = 0; i < RidCount; i++)
Rids[i] = *RtlSubAuthoritySid(SrcSid, i);
Rids[RidCount] = Rid;
RidCount++;
RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid),
RidCount,
Rids[0],
Rids[1],
Rids[2],
Rids[3],
Rids[4],
Rids[5],
Rids[6],
Rids[7],
&DstSid);
return DstSid;
}
/* EOF */

View file

@ -291,7 +291,7 @@ BuildTokenGroups(OUT PTOKEN_GROUPS *Groups,
{
SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
PTOKEN_GROUPS TokenGroups;
#define MAX_GROUPS 4
#define MAX_GROUPS 2
DWORD GroupCount = 0;
PSID Sid;
NTSTATUS Status = STATUS_SUCCESS;
@ -316,45 +316,6 @@ BuildTokenGroups(OUT PTOKEN_GROUPS *Groups,
GroupCount++;
#if 1
/* Member of 'Administrators' */
RtlAllocateAndInitializeSid(&SystemAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
&Sid);
TokenGroups->Groups[GroupCount].Sid = Sid;
TokenGroups->Groups[GroupCount].Attributes =
SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
GroupCount++;
#else
TRACE("Not adding user to Administrators group\n");
#endif
/* Member of 'Users' */
RtlAllocateAndInitializeSid(&SystemAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_USERS,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
&Sid);
TokenGroups->Groups[GroupCount].Sid = Sid;
TokenGroups->Groups[GroupCount].Attributes =
SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
GroupCount++;
/* Member of 'Authenticated users' */
RtlAllocateAndInitializeSid(&SystemAuthority,
1,