From c3b566e4d86d65124fb5bf8821f6f1d510783da5 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 5 Jan 2014 16:06:16 +0000 Subject: [PATCH] [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 --- reactos/dll/win32/lsasrv/authpackage.c | 279 +++++++++++++++++++++++++ reactos/dll/win32/lsasrv/lsasrv.h | 5 + reactos/dll/win32/lsasrv/utils.c | 36 ++++ reactos/dll/win32/msv1_0/msv1_0.c | 41 +--- 4 files changed, 321 insertions(+), 40 deletions(-) diff --git a/reactos/dll/win32/lsasrv/authpackage.c b/reactos/dll/win32/lsasrv/authpackage.c index ce959281d00..16ff508c81a 100644 --- a/reactos/dll/win32/lsasrv/authpackage.c +++ b/reactos/dll/win32/lsasrv/authpackage.c @@ -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)) diff --git a/reactos/dll/win32/lsasrv/lsasrv.h b/reactos/dll/win32/lsasrv/lsasrv.h index 50b8276472d..5f64f1d9631 100644 --- a/reactos/dll/win32/lsasrv/lsasrv.h +++ b/reactos/dll/win32/lsasrv/lsasrv.h @@ -415,4 +415,9 @@ LsapLoadString(HINSTANCE hInstance, LPWSTR lpBuffer, INT nBufferMax); +PSID +LsapAppendRidToSid( + PSID SrcSid, + ULONG Rid); + /* EOF */ diff --git a/reactos/dll/win32/lsasrv/utils.c b/reactos/dll/win32/lsasrv/utils.c index f0b87e9ad1c..0b82c9acc15 100644 --- a/reactos/dll/win32/lsasrv/utils.c +++ b/reactos/dll/win32/lsasrv/utils.c @@ -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 */ diff --git a/reactos/dll/win32/msv1_0/msv1_0.c b/reactos/dll/win32/msv1_0/msv1_0.c index 37fb0da0a4e..4c080fb5575 100644 --- a/reactos/dll/win32/msv1_0/msv1_0.c +++ b/reactos/dll/win32/msv1_0/msv1_0.c @@ -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, -- 2.17.1