mirror of
https://github.com/reactos/reactos.git
synced 2025-01-04 21:38:43 +00:00
added RosEnableThreadPrivileges() and RosResetThreadPrivileges() helper functions for easier thread privilege management
svn path=/trunk/; revision=10494
This commit is contained in:
parent
486bb2502f
commit
05d68bd490
3 changed files with 143 additions and 2 deletions
23
reactos/include/rosrtl/priv.h
Normal file
23
reactos/include/rosrtl/priv.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/* $Id: priv.h,v 1.1 2004/08/11 08:28:13 weiden Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ROSRTL_SEC_H__
|
||||||
|
#define ROSRTL_SEC_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
RosEnableThreadPrivileges(HANDLE *hToken, DWORD *Privileges, DWORD PrivilegeCount);
|
||||||
|
BOOL
|
||||||
|
RosResetThreadPrivileges(HANDLE hToken);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.13 2004/08/10 10:57:54 weiden Exp $
|
# $Id: makefile,v 1.14 2004/08/11 08:28:13 weiden Exp $
|
||||||
|
|
||||||
PATH_TO_TOP = ../..
|
PATH_TO_TOP = ../..
|
||||||
|
|
||||||
|
@ -13,7 +13,8 @@ TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a
|
||||||
THREAD_OBJECTS = \
|
THREAD_OBJECTS = \
|
||||||
thread/create.o \
|
thread/create.o \
|
||||||
thread/exit.o \
|
thread/exit.o \
|
||||||
thread/stack.o
|
thread/stack.o \
|
||||||
|
thread/priv.o
|
||||||
|
|
||||||
STRING_OBJECTS = \
|
STRING_OBJECTS = \
|
||||||
string/append.o \
|
string/append.o \
|
||||||
|
|
117
reactos/lib/rosrtl/thread/priv.c
Normal file
117
reactos/lib/rosrtl/thread/priv.c
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <rosrtl/priv.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility to copy and enable thread privileges
|
||||||
|
*
|
||||||
|
* OUT HANDLE *hPreviousToken -> Pointer to a variable that receives the previous token handle
|
||||||
|
* IN DWORD *Privileges -> Points to an array of privileges to be enabled
|
||||||
|
* IN DWORD PrivilegeCount -> Number of the privileges in the array
|
||||||
|
*
|
||||||
|
* Returns TRUE on success and copies the thread token (if any) handle that was active before impersonation.
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
RosEnableThreadPrivileges(HANDLE *hPreviousToken,
|
||||||
|
DWORD *Privileges,
|
||||||
|
DWORD PrivilegeCount)
|
||||||
|
{
|
||||||
|
HANDLE hToken;
|
||||||
|
|
||||||
|
if(hPreviousToken == NULL ||
|
||||||
|
Privileges == NULL || PrivilegeCount == 0)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Just open the thread token, we'll duplicate the handle later */
|
||||||
|
if(OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, FALSE, &hToken))
|
||||||
|
{
|
||||||
|
PTOKEN_PRIVILEGES privs;
|
||||||
|
PLUID_AND_ATTRIBUTES la;
|
||||||
|
HANDLE hNewToken;
|
||||||
|
BOOL Ret;
|
||||||
|
|
||||||
|
/* duplicate the token handle */
|
||||||
|
if(!DuplicateTokenEx(hToken, TOKEN_IMPERSONATE, NULL, SecurityImpersonation,
|
||||||
|
TokenImpersonation, &hNewToken))
|
||||||
|
{
|
||||||
|
CloseHandle(hToken);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the required space for the privilege list */
|
||||||
|
privs = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, sizeof(TOKEN_PRIVILEGES) +
|
||||||
|
((PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES)));
|
||||||
|
if(privs == NULL)
|
||||||
|
{
|
||||||
|
CloseHandle(hNewToken);
|
||||||
|
CloseHandle(hToken);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build the privilege list */
|
||||||
|
privs->PrivilegeCount = PrivilegeCount;
|
||||||
|
for(la = privs->Privileges; PrivilegeCount-- > 0; la++)
|
||||||
|
{
|
||||||
|
la->Luid.LowPart = *(Privileges++);
|
||||||
|
la->Luid.HighPart = 0;
|
||||||
|
la->Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable the token privileges */
|
||||||
|
if(!AdjustTokenPrivileges(hNewToken, FALSE, privs, 0, NULL, NULL))
|
||||||
|
{
|
||||||
|
LocalFree((HLOCAL)privs);
|
||||||
|
CloseHandle(hNewToken);
|
||||||
|
CloseHandle(hToken);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we don't need the privileges list anymore */
|
||||||
|
LocalFree((HLOCAL)privs);
|
||||||
|
|
||||||
|
/* Perform the impersonation */
|
||||||
|
Ret = SetThreadToken(NULL, hToken);
|
||||||
|
|
||||||
|
if(Ret)
|
||||||
|
{
|
||||||
|
/* only copy the previous token handle on success */
|
||||||
|
*hPreviousToken = hToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We don't need the handle to the new token anymore */
|
||||||
|
CloseHandle(hNewToken);
|
||||||
|
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility to reset the thread privileges previously changed with RosEnableThreadPrivileges()
|
||||||
|
*
|
||||||
|
* IN HANDLE hToken -> Handle of the thread token to be restored
|
||||||
|
*
|
||||||
|
* Returns TRUE on success.
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
RosResetThreadPrivileges(HANDLE hToken)
|
||||||
|
{
|
||||||
|
if(hToken != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
BOOL Ret;
|
||||||
|
|
||||||
|
/* Set the previous token handle */
|
||||||
|
Ret = SetThreadToken(NULL, hToken);
|
||||||
|
|
||||||
|
/* We don't need the handle anymore, close it */
|
||||||
|
CloseHandle(hToken);
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue