📄 misc.c
字号:
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/advapi32/sec/misc.c
* PURPOSE: Miscellaneous security functions
*/
#include <advapi32.h>
#define NDEBUG
#include <debug.h>
/* Interface to ntmarta.dll ***************************************************/
NTMARTA NtMartaStatic = { 0 };
static PNTMARTA NtMarta = NULL;
#define FindNtMartaProc(Name) \
NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
"Acc" # Name ); \
if (NtMartaStatic.Name == NULL) \
{ \
return GetLastError(); \
}
static DWORD
LoadAndInitializeNtMarta(VOID)
{
/* this code may be executed simultaneously by multiple threads in case they're
trying to initialize the interface at the same time, but that's no problem
because the pointers returned by GetProcAddress will be the same. However,
only one of the threads will change the NtMarta pointer to the NtMartaStatic
structure, the others threads will detect that there were other threads
initializing the structure faster and will release the reference to the
DLL */
NtMartaStatic.hDllInstance = LoadLibraryW(L"ntmarta.dll");
if (NtMartaStatic.hDllInstance == NULL)
{
return GetLastError();
}
#if 0
FindNtMartaProc(LookupAccountTrustee);
FindNtMartaProc(LookupAccountName);
FindNtMartaProc(LookupAccountSid);
FindNtMartaProc(SetEntriesInAList);
FindNtMartaProc(ConvertAccessToSecurityDescriptor);
FindNtMartaProc(ConvertSDToAccess);
FindNtMartaProc(ConvertAclToAccess);
FindNtMartaProc(GetAccessForTrustee);
FindNtMartaProc(GetExplicitEntries);
#endif
FindNtMartaProc(RewriteGetNamedRights);
FindNtMartaProc(RewriteSetNamedRights);
FindNtMartaProc(RewriteGetHandleRights);
FindNtMartaProc(RewriteSetHandleRights);
FindNtMartaProc(RewriteSetEntriesInAcl);
FindNtMartaProc(RewriteGetExplicitEntriesFromAcl);
FindNtMartaProc(TreeResetNamedSecurityInfo);
FindNtMartaProc(GetInheritanceSource);
FindNtMartaProc(FreeIndexArray);
return ERROR_SUCCESS;
}
DWORD
CheckNtMartaPresent(VOID)
{
DWORD ErrorCode;
if (NtMarta == NULL)
{
/* we're the first one trying to use ntmarta, initialize it and change
the pointer after initialization */
ErrorCode = LoadAndInitializeNtMarta();
if (ErrorCode == ERROR_SUCCESS)
{
/* try change the NtMarta pointer */
if (InterlockedCompareExchangePointer(&NtMarta,
&NtMartaStatic,
NULL) != NULL)
{
/* another thread initialized ntmarta in the meanwhile, release
the reference of the dll loaded. */
FreeLibrary(NtMartaStatic.hDllInstance);
}
}
#if DBG
else
{
DPRINT1("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode);
}
#endif
}
else
{
/* ntmarta was already initialized */
ErrorCode = ERROR_SUCCESS;
}
return ErrorCode;
}
VOID UnloadNtMarta(VOID)
{
if (InterlockedExchangePointer(&NtMarta,
NULL) != NULL)
{
FreeLibrary(NtMartaStatic.hDllInstance);
}
}
/******************************************************************************/
/*
* @implemented
*/
BOOL STDCALL
AreAllAccessesGranted(DWORD GrantedAccess,
DWORD DesiredAccess)
{
return((BOOL)RtlAreAllAccessesGranted(GrantedAccess,
DesiredAccess));
}
/*
* @implemented
*/
BOOL STDCALL
AreAnyAccessesGranted(DWORD GrantedAccess,
DWORD DesiredAccess)
{
return((BOOL)RtlAreAnyAccessesGranted(GrantedAccess,
DesiredAccess));
}
/******************************************************************************
* GetFileSecurityA [ADVAPI32.@]
*
* Obtains Specified information about the security of a file or directory.
*
* PARAMS
* lpFileName [I] Name of the file to get info for
* RequestedInformation [I] SE_ flags from "winnt.h"
* pSecurityDescriptor [O] Destination for security information
* nLength [I] Length of pSecurityDescriptor
* lpnLengthNeeded [O] Destination for length of returned security information
*
* RETURNS
* Success: TRUE. pSecurityDescriptor contains the requested information.
* Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
*
* NOTES
* The information returned is constrained by the callers access rights and
* privileges.
*
* @implemented
*/
BOOL WINAPI
GetFileSecurityA(LPCSTR lpFileName,
SECURITY_INFORMATION RequestedInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor,
DWORD nLength,
LPDWORD lpnLengthNeeded)
{
UNICODE_STRING FileName;
NTSTATUS Status;
BOOL bResult;
Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
(LPSTR)lpFileName);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
bResult = GetFileSecurityW(FileName.Buffer,
RequestedInformation,
pSecurityDescriptor,
nLength,
lpnLengthNeeded);
RtlFreeUnicodeString(&FileName);
return bResult;
}
/*
* @implemented
*/
BOOL WINAPI
GetFileSecurityW(LPCWSTR lpFileName,
SECURITY_INFORMATION RequestedInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor,
DWORD nLength,
LPDWORD lpnLengthNeeded)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK StatusBlock;
UNICODE_STRING FileName;
ULONG AccessMask = 0;
HANDLE FileHandle;
NTSTATUS Status;
DPRINT("GetFileSecurityW() called\n");
if (RequestedInformation &
(OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
{
AccessMask |= READ_CONTROL;
}
if (RequestedInformation & SACL_SECURITY_INFORMATION)
{
AccessMask |= ACCESS_SYSTEM_SECURITY;
}
if (!RtlDosPathNameToNtPathName_U(lpFileName,
&FileName,
NULL,
NULL))
{
DPRINT("Invalid path\n");
SetLastError(ERROR_INVALID_NAME);
return FALSE;
}
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
AccessMask,
&ObjectAttributes,
&StatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0);
RtlFreeHeap(RtlGetProcessHeap(),
0,
FileName.Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
Status = NtQuerySecurityObject(FileHandle,
RequestedInformation,
pSecurityDescriptor,
nLength,
lpnLengthNeeded);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status);
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL STDCALL
GetKernelObjectSecurity(HANDLE Handle,
SECURITY_INFORMATION RequestedInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor,
DWORD nLength,
LPDWORD lpnLengthNeeded)
{
NTSTATUS Status;
Status = NtQuerySecurityObject(Handle,
RequestedInformation,
pSecurityDescriptor,
nLength,
lpnLengthNeeded);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return(FALSE);
}
return(TRUE);
}
/******************************************************************************
* SetFileSecurityA [ADVAPI32.@]
* Sets the security of a file or directory
*
* @implemented
*/
BOOL STDCALL
SetFileSecurityA (LPCSTR lpFileName,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
UNICODE_STRING FileName;
NTSTATUS Status;
BOOL bResult;
Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
(LPSTR)lpFileName);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
bResult = SetFileSecurityW(FileName.Buffer,
SecurityInformation,
pSecurityDescriptor);
RtlFreeUnicodeString(&FileName);
return bResult;
}
/******************************************************************************
* SetFileSecurityW [ADVAPI32.@]
* Sets the security of a file or directory
*
* @implemented
*/
BOOL STDCALL
SetFileSecurityW (LPCWSTR lpFileName,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK StatusBlock;
UNICODE_STRING FileName;
ULONG AccessMask = 0;
HANDLE FileHandle;
NTSTATUS Status;
DPRINT("SetFileSecurityW() called\n");
if (SecurityInformation &
(OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
{
AccessMask |= WRITE_OWNER;
}
if (SecurityInformation & DACL_SECURITY_INFORMATION)
{
AccessMask |= WRITE_DAC;
}
if (SecurityInformation & SACL_SECURITY_INFORMATION)
{
AccessMask |= ACCESS_SYSTEM_SECURITY;
}
if (!RtlDosPathNameToNtPathName_U(lpFileName,
&FileName,
NULL,
NULL))
{
DPRINT("Invalid path\n");
SetLastError(ERROR_INVALID_NAME);
return FALSE;
}
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
AccessMask,
&ObjectAttributes,
&StatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0);
RtlFreeHeap(RtlGetProcessHeap(),
0,
FileName.Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
Status = NtSetSecurityObject(FileHandle,
SecurityInformation,
pSecurityDescriptor);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("NtSetSecurityObject() failed (Status %lx)\n", Status);
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL STDCALL
SetKernelObjectSecurity(HANDLE Handle,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor)
{
NTSTATUS Status;
Status = NtSetSecurityObject(Handle,
SecurityInformation,
SecurityDescriptor);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL
WINAPI
ImpersonateAnonymousToken(IN HANDLE ThreadHandle)
{
NTSTATUS Status;
Status = NtImpersonateAnonymousToken(ThreadHandle);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL STDCALL
ImpersonateLoggedOnUser(HANDLE hToken)
{
SECURITY_QUALITY_OF_SERVICE Qos;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE NewToken;
TOKEN_TYPE Type;
ULONG ReturnLength;
BOOL Duplicated;
NTSTATUS Status;
/* Get the token type */
Status = NtQueryInformationToken (hToken,
TokenType,
&Type,
sizeof(TOKEN_TYPE),
&ReturnLength);
if (!NT_SUCCESS(Status))
{
SetLastError (RtlNtStatusToDosError (Status));
return FALSE;
}
if (Type == TokenPrimary)
{
/* Create a duplicate impersonation token */
Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
Qos.ImpersonationLevel = SecurityImpersonation;
Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
Qos.EffectiveOnly = FALSE;
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.ObjectName = NULL;
ObjectAttributes.Attributes = 0;
ObjectAttributes.SecurityDescriptor = NULL;
ObjectAttributes.SecurityQualityOfService = &Qos;
Status = NtDuplicateToken (hToken,
TOKEN_IMPERSONATE | TOKEN_QUERY,
&ObjectAttributes,
FALSE,
TokenImpersonation,
&NewToken);
if (!NT_SUCCESS(Status))
{
SetLastError (RtlNtStatusToDosError (Status));
return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -