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