|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
Security.cpp
Abstract:
General fax server security utility functions
Author:
Eran Yariv (EranY) Feb, 2001
Revision History:
--*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <Accctrl.h>
#include <Aclapi.h>
#include "faxutil.h"
#include "faxreg.h"
#include "FaxUIConstants.h"
HANDLE EnablePrivilege ( LPCTSTR lpctstrPrivName ) /*++
Routine name : EnablePrivilege
Routine description:
Enables a specific privilege in the current thread (or process) access token
Author:
Eran Yariv (EranY), Feb, 2001
Arguments:
lpctstrPrivName [in] - Privilege to enable (e.g. SE_TAKE_OWNERSHIP_NAME)
Return Value:
INVALID_HANDLE_VALUE on failure (call GetLastError to get error code). On success, returns the handle which holds the thread/process priviledges before the change.
The caller must call ReleasePrivilege() to restore the access token state and release the handle.
--*/ { BOOL fResult; HANDLE hToken = INVALID_HANDLE_VALUE; HANDLE hOriginalThreadToken = INVALID_HANDLE_VALUE; LUID luidPriv; TOKEN_PRIVILEGES tp = {0};
DEBUG_FUNCTION_NAME( TEXT("EnablePrivileges"));
Assert (lpctstrPrivName); //
// Get the LUID of the privilege.
//
if (!LookupPrivilegeValue(NULL, lpctstrPrivName, &luidPriv)) { DebugPrintEx( DEBUG_ERR, _T("Failed to LookupPrivilegeValue. (ec: %ld)"), GetLastError ()); return INVALID_HANDLE_VALUE; }
//
// Initialize the Privileges Structure
//
tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tp.Privileges[0].Luid = luidPriv; //
// Open the Token
//
fResult = OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, FALSE, &hToken); if (fResult) { //
// Remember the thread token
//
hOriginalThreadToken = hToken; } 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
&tp, // 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; } if (INVALID_HANDLE_VALUE == hOriginalThreadToken) { //
// Using the process token
//
if (INVALID_HANDLE_VALUE != hToken) { //
// Close the original token if we aren't returning it
//
CloseHandle(hToken); } if (fResult) { //
// If we succeeded, but there was no original thread token,
// return NULL to indicate we need to do SetThreadToken(NULL, NULL) to release privs.
//
hOriginalThreadToken = NULL; } } return hOriginalThreadToken; } // EnablePrivilege
void ReleasePrivilege( HANDLE hToken ) /*++
Routine name : ReleasePrivilege
Routine description:
Resets privileges to the state prior to the corresponding EnablePrivilege() call
Author:
Eran Yariv (EranY), Feb, 2001
Arguments:
hToken [IN] - Return value from the corresponding EnablePrivilege() call
Return Value:
None.
--*/ { DEBUG_FUNCTION_NAME( TEXT("ReleasePrivilege")); if (INVALID_HANDLE_VALUE != hToken) { if(!SetThreadToken(NULL, hToken)) { DebugPrintEx(DEBUG_ERR, TEXT("SetThreadToken() failed (ec: %ld)"), GetLastError()); }
if (hToken) { if(!CloseHandle(hToken)) { DebugPrintEx(DEBUG_ERR, TEXT("CloseHandle() failed (ec: %ld)"), GetLastError()); } } } } // ReleasePrivilege
DWORD EnableProcessPrivilege(LPCTSTR lpPrivilegeName) /*++
Routine name : EnableProcessPrivilege
Routine description:
Enables process privilege.
Author:
Caliv Nir (t-nicali) Mar, 2002
Arguments:
lpPrivilegeName [in] - Pointer to a null-terminated string that specifies the name of the privilege, as defined in the Winnt.h header file. For example, this parameter could specify the constant SE_SECURITY_NAME, or its corresponding string, "SeSecurityPrivilege" Return Value:
Standard Win32 error code.
--*/ { HANDLE hToken = INVALID_HANDLE_VALUE; TOKEN_PRIVILEGES tp = {0}; LUID luidPriv;
BOOL bRet; DWORD dwRet=ERROR_SUCCESS;
DEBUG_FUNCTION_NAME( TEXT("EnableProcessPrivilege"));
Assert(lpPrivilegeName);
//
// Get the LUID of the privilege.
//
if (!LookupPrivilegeValue(NULL, lpPrivilegeName, &luidPriv)) { dwRet = GetLastError(); DebugPrintEx( DEBUG_ERR, _T("Failed to LookupPrivilegeValue. (ec: %lu)"), dwRet); goto Exit; }
//
// Initialize the Privileges Structure
//
tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tp.Privileges[0].Luid = luidPriv;
//
// Open process token
//
bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); if (FALSE == bRet) { //
// Failed to OpenProcessToken
//
dwRet = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("OpenProcessToken() failed: err = %lu"), dwRet); goto Exit; }
//
// Adjust the Token
//
bRet = AdjustTokenPrivileges(hToken, // TokenHandle
FALSE, // DisableAllPrivileges
&tp, // NewState
0, // BufferLength
NULL, // PreviousState
NULL); // ReturnLength
if (FALSE == bRet) { //
// Failed to OpenProcessToken
//
dwRet = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("AdjustTokenPrivileges() failed: err = %lu"), dwRet); goto Exit; }
Assert(ERROR_SUCCESS == dwRet); Exit: if(NULL != hToken) { if(!CloseHandle(hToken)) { DebugPrintEx( DEBUG_ERR, TEXT("CloseHandle() failed: err = %lu"), GetLastError()); } } return dwRet; }
|