354 lines
8.6 KiB
C
354 lines
8.6 KiB
C
/*++ BUILD Version: 0001 // Increment this if a change has global effects
|
||
|
||
Copyright (c) 1992-1994 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
perfsec.c
|
||
|
||
Abstract:
|
||
|
||
This file implements the _access checking functions used by the
|
||
performance registry API's
|
||
|
||
Author:
|
||
|
||
Bob Watson (a-robw)
|
||
|
||
Revision History:
|
||
|
||
8-Mar-95 Created (and extracted from Perflib.c
|
||
|
||
--*/
|
||
#define UNICODE
|
||
//
|
||
// Include files
|
||
//
|
||
#pragma warning(disable:4306)
|
||
#include <nt.h>
|
||
#include <ntrtl.h>
|
||
#include <nturtl.h>
|
||
#include <windows.h>
|
||
#include "ntconreg.h"
|
||
#include "perflib.h"
|
||
#pragma warning(default:4306)
|
||
|
||
#define INITIAL_SID_BUFFER_SIZE 4096
|
||
#define FREE_IF_ALLOC(x) if ((x) != NULL) {FREEMEM(x);}
|
||
|
||
BOOL
|
||
TestTokenForPriv(
|
||
HANDLE hToken,
|
||
LPTSTR szPrivName
|
||
)
|
||
/***************************************************************************\
|
||
* TestTokenForPriv
|
||
*
|
||
* Returns TRUE if the token passed has the specified privilege
|
||
*
|
||
* The token handle passed must have TOKEN_QUERY access.
|
||
*
|
||
* History:
|
||
* 03-07-95 a-robw Created
|
||
\***************************************************************************/
|
||
{
|
||
BOOL bStatus;
|
||
LUID PrivLuid;
|
||
PRIVILEGE_SET PrivSet;
|
||
LUID_AND_ATTRIBUTES PrivLAndA[1];
|
||
|
||
BOOL bReturn = FALSE;
|
||
|
||
// get value of priv
|
||
|
||
bStatus = LookupPrivilegeValue (
|
||
NULL,
|
||
szPrivName,
|
||
&PrivLuid);
|
||
|
||
if (!bStatus) {
|
||
// unable to lookup privilege
|
||
goto Exit_Point;
|
||
}
|
||
|
||
// build Privilege Set for function call
|
||
|
||
PrivLAndA[0].Luid = PrivLuid;
|
||
PrivLAndA[0].Attributes = 0;
|
||
|
||
PrivSet.PrivilegeCount = 1;
|
||
PrivSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
|
||
PrivSet.Privilege[0] = PrivLAndA[0];
|
||
|
||
// check for the specified priv in the token
|
||
|
||
bStatus = PrivilegeCheck (
|
||
hToken,
|
||
&PrivSet,
|
||
&bReturn);
|
||
|
||
if (bStatus) {
|
||
SetLastError (ERROR_SUCCESS);
|
||
}
|
||
|
||
//
|
||
// Tidy up
|
||
//
|
||
Exit_Point:
|
||
|
||
return(bReturn);
|
||
}
|
||
|
||
BOOL
|
||
TestClientForPriv (
|
||
BOOL *pbThread,
|
||
LPTSTR szPrivName
|
||
)
|
||
/***************************************************************************\
|
||
* TestClientForPriv
|
||
*
|
||
* Returns TRUE if our client has the specified privilege
|
||
* Otherwise, returns FALSE.
|
||
*
|
||
\***************************************************************************/
|
||
{
|
||
BOOL bResult;
|
||
BOOL bIgnore;
|
||
DWORD dwLastError;
|
||
|
||
BOOL bThreadFlag = FALSE; // assume data is from process or an error occurred
|
||
|
||
HANDLE hClient;
|
||
|
||
SetLastError (ERROR_SUCCESS);
|
||
|
||
bResult = OpenThreadToken(GetCurrentThread(), // This Thread
|
||
TOKEN_QUERY, //DesiredAccess
|
||
FALSE, // use context of calling thread
|
||
&hClient); //TokenHandle
|
||
if (!bResult) {
|
||
// unable to get a Thread Token, try a Process Token
|
||
bResult = OpenProcessToken(GetCurrentProcess(), // This Process
|
||
TOKEN_QUERY, //DesiredAccess
|
||
&hClient); //TokenHandle
|
||
} else {
|
||
// data is from current THREAD
|
||
bThreadFlag = TRUE;
|
||
}
|
||
|
||
if (bResult) {
|
||
try {
|
||
bResult = TestTokenForPriv( hClient, szPrivName );
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
bResult = FALSE;
|
||
}
|
||
bIgnore = CloseHandle( hClient );
|
||
ASSERT(bIgnore == TRUE);
|
||
} else {
|
||
dwLastError = GetLastError ();
|
||
}
|
||
|
||
// set thread flag if present
|
||
if (pbThread != NULL) {
|
||
try {
|
||
*pbThread = bThreadFlag;
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
SetLastError (ERROR_INVALID_PARAMETER);
|
||
}
|
||
}
|
||
|
||
return(bResult);
|
||
}
|
||
|
||
LONG
|
||
GetProcessNameColMeth (
|
||
VOID
|
||
)
|
||
{
|
||
NTSTATUS Status;
|
||
HANDLE hPerflibKey;
|
||
OBJECT_ATTRIBUTES oaPerflibKey;
|
||
UNICODE_STRING PerflibSubKeyString;
|
||
UNICODE_STRING NameInfoValueString;
|
||
LONG lReturn = PNCM_SYSTEM_INFO;
|
||
PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
|
||
DWORD dwBufLen;
|
||
DWORD dwRetBufLen;
|
||
PDWORD pdwValue;
|
||
|
||
RtlInitUnicodeString (
|
||
&PerflibSubKeyString,
|
||
L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib");
|
||
|
||
InitializeObjectAttributes(
|
||
&oaPerflibKey,
|
||
&PerflibSubKeyString,
|
||
OBJ_CASE_INSENSITIVE,
|
||
NULL,
|
||
NULL
|
||
);
|
||
|
||
Status = NtOpenKey(
|
||
&hPerflibKey,
|
||
MAXIMUM_ALLOWED,
|
||
&oaPerflibKey
|
||
);
|
||
|
||
if (NT_SUCCESS (Status)) {
|
||
// registry key opened, now read value.
|
||
// allocate enough room for the structure, - the last
|
||
// UCHAR in the struct, but + the data buffer (a dword)
|
||
|
||
dwBufLen = sizeof(KEY_VALUE_PARTIAL_INFORMATION) -
|
||
sizeof(UCHAR) + sizeof (DWORD);
|
||
|
||
pKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ALLOCMEM (dwBufLen);
|
||
|
||
if (pKeyInfo != NULL) {
|
||
// initialize value name string
|
||
RtlInitUnicodeString (
|
||
&NameInfoValueString,
|
||
L"CollectUnicodeProcessNames");
|
||
|
||
dwRetBufLen = 0;
|
||
Status = NtQueryValueKey (
|
||
hPerflibKey,
|
||
&NameInfoValueString,
|
||
KeyValuePartialInformation,
|
||
(PVOID)pKeyInfo,
|
||
dwBufLen,
|
||
&dwRetBufLen);
|
||
|
||
if (NT_SUCCESS(Status)) {
|
||
// check value of return data buffer
|
||
pdwValue = (PDWORD)&pKeyInfo->Data[0];
|
||
if (*pdwValue == PNCM_MODULE_FILE) {
|
||
lReturn = PNCM_MODULE_FILE;
|
||
} else {
|
||
// all other values will cause this routine to return
|
||
// the default value of PNCM_SYSTEM_INFO;
|
||
}
|
||
}
|
||
|
||
FREEMEM (pKeyInfo);
|
||
}
|
||
// close handle
|
||
NtClose (hPerflibKey);
|
||
}
|
||
|
||
return lReturn;
|
||
}
|
||
|
||
LONG
|
||
GetPerfDataAccess (
|
||
VOID
|
||
)
|
||
{
|
||
NTSTATUS Status;
|
||
HANDLE hPerflibKey;
|
||
OBJECT_ATTRIBUTES oaPerflibKey;
|
||
UNICODE_STRING PerflibSubKeyString;
|
||
UNICODE_STRING NameInfoValueString;
|
||
LONG lReturn = CPSR_EVERYONE;
|
||
PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
|
||
DWORD dwBufLen;
|
||
DWORD dwRetBufLen;
|
||
PDWORD pdwValue;
|
||
|
||
RtlInitUnicodeString (
|
||
&PerflibSubKeyString,
|
||
L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib");
|
||
|
||
InitializeObjectAttributes(
|
||
&oaPerflibKey,
|
||
&PerflibSubKeyString,
|
||
OBJ_CASE_INSENSITIVE,
|
||
NULL,
|
||
NULL
|
||
);
|
||
|
||
Status = NtOpenKey(
|
||
&hPerflibKey,
|
||
MAXIMUM_ALLOWED,
|
||
&oaPerflibKey
|
||
);
|
||
|
||
if (NT_SUCCESS (Status)) {
|
||
// registry key opened, now read value.
|
||
// allocate enough room for the structure, - the last
|
||
// UCHAR in the struct, but + the data buffer (a dword)
|
||
|
||
dwBufLen = sizeof(KEY_VALUE_PARTIAL_INFORMATION) -
|
||
sizeof(UCHAR) + sizeof (DWORD);
|
||
|
||
pKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ALLOCMEM (dwBufLen);
|
||
|
||
if (pKeyInfo != NULL) {
|
||
|
||
// see if the user right should be checked
|
||
|
||
// init value name string
|
||
RtlInitUnicodeString (
|
||
&NameInfoValueString,
|
||
L"CheckProfileSystemRight");
|
||
|
||
dwRetBufLen = 0;
|
||
Status = NtQueryValueKey (
|
||
hPerflibKey,
|
||
&NameInfoValueString,
|
||
KeyValuePartialInformation,
|
||
(PVOID)pKeyInfo,
|
||
dwBufLen,
|
||
&dwRetBufLen);
|
||
|
||
if (NT_SUCCESS(Status)) {
|
||
// check value of return data buffer
|
||
pdwValue = (PDWORD)&pKeyInfo->Data[0];
|
||
if (*pdwValue == CPSR_CHECK_ENABLED) {
|
||
lReturn = CPSR_CHECK_PRIVS;
|
||
} else {
|
||
// all other values will cause this routine to return
|
||
// the default value of CPSR_EVERYONE
|
||
}
|
||
}
|
||
|
||
FREEMEM (pKeyInfo);
|
||
}
|
||
// close handle
|
||
NtClose (hPerflibKey);
|
||
}
|
||
|
||
return lReturn;
|
||
}
|
||
|
||
BOOL
|
||
TestClientForAccess (
|
||
VOID
|
||
)
|
||
/***************************************************************************\
|
||
* TestClientForAccess
|
||
*
|
||
* Returns TRUE if our client is allowed to read the perflib key.
|
||
* Otherwise, returns FALSE.
|
||
*
|
||
\***************************************************************************/
|
||
{
|
||
HKEY hKeyPerflib;
|
||
DWORD dwStatus;
|
||
BOOL bResult = FALSE;
|
||
|
||
dwStatus = RegOpenKeyExW(
|
||
HKEY_LOCAL_MACHINE,
|
||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
|
||
0L,
|
||
KEY_READ,
|
||
& hKeyPerflib);
|
||
|
||
if (dwStatus == ERROR_SUCCESS) {
|
||
RegCloseKey(hKeyPerflib);
|
||
bResult = TRUE;
|
||
}
|
||
|
||
return (bResult);
|
||
}
|