|
|
/*++
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; }
|