154 lines
4.9 KiB
C++
154 lines
4.9 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1997 - 1999
|
|
//
|
|
// File: priv.cpp
|
|
//
|
|
// Provides support for enabling/disabling privileges
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: EnablePrivileges
|
|
|
|
SYNOPSIS: Enables the given privileges in the current token
|
|
|
|
ENTRY: pdwPrivileges - list of privileges to enable
|
|
|
|
RETURNS: On success, the previous thread handle (if present) or NULL
|
|
On failure, INVALID_HANDLE_VALUE
|
|
|
|
NOTES: The returned handle should be passed to ReleasePrivileges
|
|
to ensure proper cleanup. Otherwise, if not NULL or
|
|
INVALID_HANDLE_VALUE it should be closed with CloseHandle.
|
|
|
|
HISTORY:
|
|
JeffreyS 08-Oct-1996 Created
|
|
|
|
********************************************************************/
|
|
HANDLE EnablePrivileges(PDWORD pdwPrivileges, ULONG cPrivileges)
|
|
{
|
|
BOOL fResult;
|
|
HANDLE hToken;
|
|
HANDLE hOriginalThreadToken;
|
|
PTOKEN_PRIVILEGES ptp;
|
|
ULONG nBufferSize;
|
|
|
|
if (!pdwPrivileges || !cPrivileges)
|
|
return INVALID_HANDLE_VALUE;
|
|
|
|
// Note that TOKEN_PRIVILEGES includes a single LUID_AND_ATTRIBUTES
|
|
nBufferSize = sizeof(TOKEN_PRIVILEGES) + (cPrivileges - 1)*sizeof(LUID_AND_ATTRIBUTES);
|
|
ptp = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, nBufferSize);
|
|
if (!ptp)
|
|
return INVALID_HANDLE_VALUE;
|
|
|
|
//
|
|
// Initialize the Privileges Structure
|
|
//
|
|
ptp->PrivilegeCount = cPrivileges;
|
|
for (ULONG i = 0; i < cPrivileges; i++)
|
|
{
|
|
//ptp->Privileges[i].Luid = RtlConvertUlongToLuid(*pdwPrivileges++);
|
|
ptp->Privileges[i].Luid.LowPart = *pdwPrivileges++;
|
|
ptp->Privileges[i].Luid.HighPart = 0;
|
|
ptp->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED;
|
|
}
|
|
|
|
//
|
|
// Open the Token
|
|
//
|
|
hToken = hOriginalThreadToken = INVALID_HANDLE_VALUE;
|
|
fResult = OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, FALSE, &hToken);
|
|
if (fResult)
|
|
hOriginalThreadToken = hToken; // Remember the thread token
|
|
else
|
|
fResult = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken);
|
|
|
|
if (fResult)
|
|
{
|
|
HANDLE hNewToken;
|
|
|
|
//
|
|
// Duplicate that Token
|
|
//
|
|
fResult = DuplicateTokenEx(hToken,
|
|
TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
|
NULL, // PSECURITY_ATTRIBUTES
|
|
SecurityImpersonation, // SECURITY_IMPERSONATION_LEVEL
|
|
TokenImpersonation, // TokenType
|
|
&hNewToken); // Duplicate token
|
|
if (fResult)
|
|
{
|
|
//
|
|
// Add new privileges
|
|
//
|
|
fResult = AdjustTokenPrivileges(hNewToken, // TokenHandle
|
|
FALSE, // DisableAllPrivileges
|
|
ptp, // NewState
|
|
0, // BufferLength
|
|
NULL, // PreviousState
|
|
NULL); // ReturnLength
|
|
if (fResult)
|
|
{
|
|
//
|
|
// Begin impersonating with the new token
|
|
//
|
|
fResult = SetThreadToken(NULL, hNewToken);
|
|
}
|
|
|
|
CloseHandle(hNewToken);
|
|
}
|
|
}
|
|
|
|
// If something failed, don't return a token
|
|
if (!fResult)
|
|
hOriginalThreadToken = INVALID_HANDLE_VALUE;
|
|
|
|
// Close the original token if we aren't returning it
|
|
if (hOriginalThreadToken == INVALID_HANDLE_VALUE && hToken != INVALID_HANDLE_VALUE)
|
|
CloseHandle(hToken);
|
|
|
|
// If we succeeded, but there was no original thread token,
|
|
// return NULL to indicate we need to do SetThreadToken(NULL, NULL)
|
|
// to release privs.
|
|
if (fResult && hOriginalThreadToken == INVALID_HANDLE_VALUE)
|
|
hOriginalThreadToken = NULL;
|
|
|
|
LocalFree(ptp);
|
|
|
|
return hOriginalThreadToken;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: ReleasePrivileges
|
|
|
|
SYNOPSIS: Resets privileges to the state prior to the corresponding
|
|
EnablePrivileges call.
|
|
|
|
ENTRY: hToken - result of call to EnablePrivileges
|
|
|
|
RETURNS: nothing
|
|
|
|
HISTORY:
|
|
JeffreyS 08-Oct-1996 Created
|
|
|
|
********************************************************************/
|
|
void ReleasePrivileges(HANDLE hToken)
|
|
{
|
|
if (INVALID_HANDLE_VALUE != hToken)
|
|
{
|
|
SetThreadToken(NULL, hToken);
|
|
if (hToken)
|
|
CloseHandle(hToken);
|
|
}
|
|
}
|