added RosEnableThreadPrivileges() and RosResetThreadPrivileges() helper functions for easier thread privilege management

svn path=/trunk/; revision=10494
This commit is contained in:
Thomas Bluemel 2004-08-11 08:28:13 +00:00
parent 486bb2502f
commit 05d68bd490
3 changed files with 143 additions and 2 deletions

View 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 */

View file

@ -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 = ../..
@ -13,7 +13,8 @@ TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a
THREAD_OBJECTS = \
thread/create.o \
thread/exit.o \
thread/stack.o
thread/stack.o \
thread/priv.o
STRING_OBJECTS = \
string/append.o \

View 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;
}