Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

211 lines
5.6 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
All rights reserved
Module Name:
priv.cxx
Abstract:
This file provides useful accssors and mutators.
Author:
Larry Zhu (LZhu) January 14, 2002 Created
Environment:
User Mode -Win32
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "priv.hxx"
TPrivilege::TPrivilege(
IN ULONG Privilege,
IN BOOLEAN bEnable
) : m_Privilege(Privilege),
m_bEnable(bEnable),
m_hToken(NULL),
m_Status(STATUS_UNSUCCESSFUL)
{
m_Status DBGCHK = Initialize();
}
TPrivilege::~TPrivilege(
VOID
)
{
if (m_hToken)
{
TNtStatus Status;
BOOLEAN bWasEnabled = FALSE;
LUID LuidPrivilege = {0};
PTOKEN_PRIVILEGES pNewPrivileges = NULL;
PTOKEN_PRIVILEGES pOldPrivileges = NULL;
ULONG cbReturnLength = 0;
UCHAR Buffer1[sizeof(TOKEN_PRIVILEGES) + ((1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES))] = {0};
UCHAR Buffer2[sizeof(TOKEN_PRIVILEGES) + ((1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES))] = {0};
pNewPrivileges = (PTOKEN_PRIVILEGES)Buffer1;
pOldPrivileges = (PTOKEN_PRIVILEGES)Buffer2;
LuidPrivilege = RtlConvertUlongToLuid(m_Privilege);
pNewPrivileges->PrivilegeCount = 1;
pNewPrivileges->Privileges[0].Luid = LuidPrivilege;
pNewPrivileges->Privileges[0].Attributes = !m_bEnable ? SE_PRIVILEGE_ENABLED : 0;
Status DBGCHK = NtAdjustPrivilegesToken(
m_hToken, // TokenHandle
FALSE, // DisableAllPrivileges
pNewPrivileges, // NewPrivileges
sizeof(Buffer1), // BufferLength
pOldPrivileges, // PreviousState (OPTIONAL)
&cbReturnLength // ReturnLength
);
if (NT_SUCCESS(Status))
{
if (pOldPrivileges->PrivilegeCount == 0)
{
bWasEnabled = m_bEnable;
}
else
{
bWasEnabled = (pOldPrivileges->Privileges[0].Attributes & SE_PRIVILEGE_ENABLED) ? TRUE : FALSE;
}
SspiPrint(SSPI_LOG, TEXT("TPrivilege::~TPrivilege %s privilege %#x for token %p (WasEnable? %#x)\n"),
!m_bEnable ? TEXT("enables") : TEXT("disables"),
m_Privilege,
m_hToken,
bWasEnabled);
}
NtClose(m_hToken);
}
}
NTSTATUS
TPrivilege::Validate(
VOID
) const
{
return m_Status;
}
/******************************************************************************
Private Methods
******************************************************************************/
NTSTATUS
TPrivilege::Initialize(
VOID
)
{
TNtStatus Status = STATUS_UNSUCCESSFUL;
LUID LuidPrivilege = {0};
PTOKEN_PRIVILEGES pNewPrivileges = NULL;
PTOKEN_PRIVILEGES pOldPrivileges = NULL;
HANDLE hToken = NULL;
ULONG cbReturnLength = 0;
BOOLEAN bWasEnabled = FALSE;
BOOLEAN bIsImpersonation = TRUE;
UCHAR Buffer1[sizeof(TOKEN_PRIVILEGES) + ((1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES))] = {0};
UCHAR Buffer2[sizeof(TOKEN_PRIVILEGES) + ((1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES))] = {0};
pNewPrivileges = (PTOKEN_PRIVILEGES) Buffer1;
pOldPrivileges = (PTOKEN_PRIVILEGES) Buffer2;
DBGCFG1(Status, STATUS_NO_TOKEN);
Status DBGCHK = NtOpenThreadToken(
NtCurrentThread(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
FALSE,
&hToken
);
if (STATUS_NO_TOKEN == (NTSTATUS) Status)
{
bIsImpersonation = FALSE;
Status DBGCHK = NtOpenProcessToken(
NtCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken
);
}
if (NT_SUCCESS(Status))
{
LuidPrivilege = RtlConvertUlongToLuid(m_Privilege);
pNewPrivileges->PrivilegeCount = 1;
pNewPrivileges->Privileges[0].Luid = LuidPrivilege;
pNewPrivileges->Privileges[0].Attributes = m_bEnable ? SE_PRIVILEGE_ENABLED : 0;
Status DBGCHK = NtAdjustPrivilegesToken(
hToken, // TokenHandle
FALSE, // DisableAllPrivileges
pNewPrivileges, // NewPrivileges
sizeof(Buffer1), // BufferLength
pOldPrivileges, // PreviousState (OPTIONAL)
&cbReturnLength // ReturnLength
);
}
if (NT_SUCCESS(Status))
{
if (pOldPrivileges->PrivilegeCount == 0)
{
bWasEnabled = m_bEnable;
}
else
{
bWasEnabled = (pOldPrivileges->Privileges[0].Attributes & SE_PRIVILEGE_ENABLED) ? TRUE : FALSE;
}
if ((!bWasEnabled && m_bEnable) || (bWasEnabled && !m_bEnable))
{
m_hToken = hToken;
hToken = NULL;
SspiPrint(SSPI_LOG, TEXT("TPrivilege::Initialize %s privilege %#x for %s token %p\n"),
m_bEnable ? TEXT("enables") : TEXT("disables"),
m_Privilege,
bIsImpersonation ? TEXT("thread") : TEXT("process"),
m_hToken);
}
}
//
// Map the success code NOT_ALL_ASSIGNED to an appropriate error
// since we're only trying to adjust the one privilege.
//
if (STATUS_NOT_ALL_ASSIGNED == (NTSTATUS) Status )
{
Status DBGCHK = STATUS_PRIVILEGE_NOT_HELD;
}
if (hToken)
{
NtClose(hToken);
}
return Status;
}