[LSASRV][MSV1_0]

- Create the privilege set for the logon token based on the users group membrships.
- Remove the hard-coded privilege set.

svn path=/trunk/; revision=61493
This commit is contained in:
Eric Kohl 2014-01-02 20:02:33 +00:00
parent d4645183ce
commit 498a39835d
2 changed files with 147 additions and 93 deletions

View file

@ -94,6 +94,9 @@ typedef struct _AUTH_PACKAGE
PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser;
} AUTH_PACKAGE, *PAUTH_PACKAGE;
VOID
NTAPI
LsaIFree_LSAPR_PRIVILEGE_SET(IN PLSAPR_PRIVILEGE_SET Ptr);
/* GLOBALS *****************************************************************/
@ -101,6 +104,11 @@ static LIST_ENTRY PackageListHead;
static ULONG PackageId;
static LSA_DISPATCH_TABLE DispatchTable;
#define CONST_LUID(x1, x2) {x1, x2}
static const LUID SeChangeNotifyPrivilege = CONST_LUID(SE_CHANGE_NOTIFY_PRIVILEGE, 0);
static const LUID SeCreateGlobalPrivilege = CONST_LUID(SE_CREATE_GLOBAL_PRIVILEGE, 0);
static const LUID SeImpersonatePrivilege = CONST_LUID(SE_IMPERSONATE_PRIVILEGE, 0);
/* FUNCTIONS ***************************************************************/
@ -936,6 +944,137 @@ LsapAddTokenDefaultDacl(
}
static
NTSTATUS
LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges,
PLSAPR_LUID_AND_ATTRIBUTES Privilege)
{
PTOKEN_PRIVILEGES LocalPrivileges;
ULONG Length, TokenPrivilegeCount, i;
NTSTATUS Status = STATUS_SUCCESS;
if (*TokenPrivileges == NULL)
{
Length = sizeof(TOKEN_PRIVILEGES) +
(1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
0,
Length);
if (LocalPrivileges == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
LocalPrivileges->PrivilegeCount = 1;
LocalPrivileges->Privileges[0].Luid = Privilege->Luid;
LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes;
}
else
{
TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount;
for (i = 0; i < TokenPrivilegeCount; i++)
{
if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid))
return STATUS_SUCCESS;
}
Length = sizeof(TOKEN_PRIVILEGES) +
(TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
0,
Length);
if (LocalPrivileges == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1;
for (i = 0; i < TokenPrivilegeCount; i++)
{
LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid;
LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes;
}
LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid;
LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes;
RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges);
}
*TokenPrivileges = LocalPrivileges;
return Status;
}
static
NTSTATUS
LsapSetPrivileges(
IN PVOID TokenInformation,
IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
{
PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
LSAPR_HANDLE PolicyHandle = NULL;
LSAPR_HANDLE AccountHandle = NULL;
PLSAPR_PRIVILEGE_SET Privileges = NULL;
ULONG i, j;
NTSTATUS Status;
if (TokenInformationType == LsaTokenInformationV1)
{
TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
Status = LsarOpenPolicy(NULL,
NULL,
0,
&PolicyHandle);
if (!NT_SUCCESS(Status))
return Status;
for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
{
Status = LsarOpenAccount(PolicyHandle,
TokenInfo1->Groups->Groups[i].Sid,
ACCOUNT_VIEW,
&AccountHandle);
if (NT_SUCCESS(Status))
{
Status = LsarEnumeratePrivilegesAccount(AccountHandle,
&Privileges);
if (NT_SUCCESS(Status))
{
for (j = 0; j < Privileges->PrivilegeCount; j++)
{
Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges,
&(Privileges->Privilege[j]));
if (!NT_SUCCESS(Status))
return Status;
}
LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
Privileges = NULL;
}
}
LsarClose(&AccountHandle);
}
LsarClose(&PolicyHandle);
if (TokenInfo1->Privileges != NULL)
{
for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++)
{
if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) ||
RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) ||
RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege))
{
TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
}
}
}
}
return STATUS_SUCCESS;
}
NTSTATUS
LsapLogonUser(PLSA_API_MSG RequestMsg,
PLSAP_LOGON_CONTEXT LogonContext)
@ -1108,6 +1247,14 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
goto done;
}
Status = LsapSetPrivileges(TokenInformation,
TokenInformationType);
if (!NT_SUCCESS(Status))
{
ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status);
goto done;
}
if (TokenInformationType == LsaTokenInformationV1)
{
TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;

View file

@ -381,92 +381,6 @@ BuildTokenGroups(OUT PTOKEN_GROUPS *Groups,
}
static
NTSTATUS
BuildTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges)
{
/* FIXME shouldn't use hard-coded list of privileges */
static struct
{
LPCWSTR PrivName;
DWORD Attributes;
}
DefaultPrivs[] =
{
{ L"SeMachineAccountPrivilege", 0 },
{ L"SeSecurityPrivilege", 0 },
{ L"SeTakeOwnershipPrivilege", 0 },
{ L"SeLoadDriverPrivilege", 0 },
{ L"SeSystemProfilePrivilege", 0 },
{ L"SeSystemtimePrivilege", 0 },
{ L"SeProfileSingleProcessPrivilege", 0 },
{ L"SeIncreaseBasePriorityPrivilege", 0 },
{ L"SeCreatePagefilePrivilege", 0 },
{ L"SeBackupPrivilege", 0 },
{ L"SeRestorePrivilege", 0 },
{ L"SeShutdownPrivilege", 0 },
{ L"SeDebugPrivilege", 0 },
{ L"SeSystemEnvironmentPrivilege", 0 },
{ L"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
{ L"SeRemoteShutdownPrivilege", 0 },
{ L"SeUndockPrivilege", 0 },
{ L"SeEnableDelegationPrivilege", 0 },
{ L"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
{ L"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }
};
PTOKEN_PRIVILEGES Privileges = NULL;
ULONG i;
RPC_UNICODE_STRING PrivilegeName;
LSAPR_HANDLE PolicyHandle = NULL;
NTSTATUS Status = STATUS_SUCCESS;
Status = LsaIOpenPolicyTrusted(&PolicyHandle);
if (!NT_SUCCESS(Status))
{
goto done;
}
/* Allocate and initialize token privileges */
Privileges = DispatchTable.AllocateLsaHeap(sizeof(TOKEN_PRIVILEGES) +
sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]) *
sizeof(LUID_AND_ATTRIBUTES));
if (Privileges == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
Privileges->PrivilegeCount = 0;
for (i = 0; i < sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]); i++)
{
PrivilegeName.Length = wcslen(DefaultPrivs[i].PrivName) * sizeof(WCHAR);
PrivilegeName.MaximumLength = PrivilegeName.Length + sizeof(WCHAR);
PrivilegeName.Buffer = (LPWSTR)DefaultPrivs[i].PrivName;
Status = LsarLookupPrivilegeValue(PolicyHandle,
&PrivilegeName,
&Privileges->Privileges[Privileges->PrivilegeCount].Luid);
if (!NT_SUCCESS(Status))
{
WARN("Can't set privilege %S\n", DefaultPrivs[i].PrivName);
}
else
{
Privileges->Privileges[Privileges->PrivilegeCount].Attributes = DefaultPrivs[i].Attributes;
Privileges->PrivilegeCount++;
}
}
*TokenPrivileges = Privileges;
done:
if (PolicyHandle != NULL)
LsarClose(&PolicyHandle);
return Status;
}
static
NTSTATUS
BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1 *TokenInformation,
@ -505,10 +419,6 @@ BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1 *TokenInformation,
if (!NT_SUCCESS(Status))
goto done;
Status = BuildTokenPrivileges(&Buffer->Privileges);
if (!NT_SUCCESS(Status))
goto done;
*TokenInformation = Buffer;
done:
@ -533,9 +443,6 @@ done:
if (Buffer->PrimaryGroup.PrimaryGroup != NULL)
DispatchTable.FreeLsaHeap(Buffer->PrimaryGroup.PrimaryGroup);
if (Buffer->Privileges != NULL)
DispatchTable.FreeLsaHeap(Buffer->Privileges);
if (Buffer->DefaultDacl.DefaultDacl != NULL)
DispatchTable.FreeLsaHeap(Buffer->DefaultDacl.DefaultDacl);