mirror of
https://github.com/reactos/reactos.git
synced 2024-10-29 19:13:58 +00:00
9ea495ba33
svn path=/branches/header-work/; revision=45691
314 lines
8 KiB
C
314 lines
8 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS system libraries
|
|
* FILE: lib/rtl/security.c
|
|
* PURPOSE: Security related functions and Security Objects
|
|
* PROGRAMMER: Eric Kohl
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include <rtl.h>
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
NTSTATUS NTAPI
|
|
RtlImpersonateSelf(IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
|
|
{
|
|
HANDLE ProcessToken;
|
|
HANDLE ImpersonationToken;
|
|
NTSTATUS Status;
|
|
OBJECT_ATTRIBUTES ObjAttr;
|
|
SECURITY_QUALITY_OF_SERVICE Sqos;
|
|
|
|
PAGED_CODE_RTL();
|
|
|
|
Status = ZwOpenProcessToken(NtCurrentProcess(),
|
|
TOKEN_DUPLICATE,
|
|
&ProcessToken);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("NtOpenProcessToken() failed (Status %lx)\n", Status);
|
|
return(Status);
|
|
}
|
|
|
|
Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
|
|
Sqos.ImpersonationLevel = ImpersonationLevel;
|
|
Sqos.ContextTrackingMode = 0;
|
|
Sqos.EffectiveOnly = FALSE;
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjAttr,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
ObjAttr.SecurityQualityOfService = &Sqos;
|
|
|
|
Status = ZwDuplicateToken(ProcessToken,
|
|
TOKEN_IMPERSONATE,
|
|
&ObjAttr,
|
|
Sqos.EffectiveOnly, /* why both here _and_ in Sqos? */
|
|
TokenImpersonation,
|
|
&ImpersonationToken);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("NtDuplicateToken() failed (Status %lx)\n", Status);
|
|
NtClose(ProcessToken);
|
|
return(Status);
|
|
}
|
|
|
|
Status = ZwSetInformationThread(NtCurrentThread(),
|
|
ThreadImpersonationToken,
|
|
&ImpersonationToken,
|
|
sizeof(HANDLE));
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("NtSetInformationThread() failed (Status %lx)\n", Status);
|
|
}
|
|
|
|
ZwClose(ImpersonationToken);
|
|
ZwClose(ProcessToken);
|
|
|
|
return(Status);
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlAcquirePrivilege(IN PULONG Privilege,
|
|
IN ULONG NumPriv,
|
|
IN ULONG Flags,
|
|
OUT PVOID *ReturnedState)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
VOID
|
|
NTAPI
|
|
RtlReleasePrivilege(IN PVOID ReturnedState)
|
|
{
|
|
UNIMPLEMENTED;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
NTSTATUS NTAPI
|
|
RtlAdjustPrivilege(IN ULONG Privilege,
|
|
IN BOOLEAN Enable,
|
|
IN BOOLEAN CurrentThread,
|
|
OUT PBOOLEAN Enabled)
|
|
{
|
|
TOKEN_PRIVILEGES NewState;
|
|
TOKEN_PRIVILEGES OldState;
|
|
ULONG ReturnLength;
|
|
HANDLE TokenHandle;
|
|
NTSTATUS Status;
|
|
|
|
PAGED_CODE_RTL();
|
|
|
|
DPRINT ("RtlAdjustPrivilege() called\n");
|
|
|
|
if (CurrentThread)
|
|
{
|
|
Status = ZwOpenThreadToken (NtCurrentThread (),
|
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
|
FALSE,
|
|
&TokenHandle);
|
|
}
|
|
else
|
|
{
|
|
Status = ZwOpenProcessToken (NtCurrentProcess (),
|
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
|
&TokenHandle);
|
|
}
|
|
|
|
if (!NT_SUCCESS (Status))
|
|
{
|
|
DPRINT1 ("Retrieving token handle failed (Status %lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
OldState.PrivilegeCount = 1;
|
|
|
|
NewState.PrivilegeCount = 1;
|
|
NewState.Privileges[0].Luid.LowPart = Privilege;
|
|
NewState.Privileges[0].Luid.HighPart = 0;
|
|
NewState.Privileges[0].Attributes = (Enable) ? SE_PRIVILEGE_ENABLED : 0;
|
|
|
|
Status = ZwAdjustPrivilegesToken (TokenHandle,
|
|
FALSE,
|
|
&NewState,
|
|
sizeof(TOKEN_PRIVILEGES),
|
|
&OldState,
|
|
&ReturnLength);
|
|
ZwClose (TokenHandle);
|
|
if (Status == STATUS_NOT_ALL_ASSIGNED)
|
|
{
|
|
DPRINT1 ("Failed to assign all privileges\n");
|
|
return STATUS_PRIVILEGE_NOT_HELD;
|
|
}
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1 ("NtAdjustPrivilegesToken() failed (Status %lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
if (OldState.PrivilegeCount == 0)
|
|
{
|
|
*Enabled = Enable;
|
|
}
|
|
else
|
|
{
|
|
*Enabled = (OldState.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED);
|
|
}
|
|
|
|
DPRINT ("RtlAdjustPrivilege() done\n");
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlDeleteSecurityObject(IN PSECURITY_DESCRIPTOR *ObjectDescriptor)
|
|
{
|
|
DPRINT("RtlDeleteSecurityObject(%p)\n", ObjectDescriptor);
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(),
|
|
0,
|
|
*ObjectDescriptor);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlNewSecurityObject(IN PSECURITY_DESCRIPTOR ParentDescriptor,
|
|
IN PSECURITY_DESCRIPTOR CreatorDescriptor,
|
|
OUT PSECURITY_DESCRIPTOR *NewDescriptor,
|
|
IN BOOLEAN IsDirectoryObject,
|
|
IN HANDLE Token,
|
|
IN PGENERIC_MAPPING GenericMapping)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlQuerySecurityObject(IN PSECURITY_DESCRIPTOR ObjectDescriptor,
|
|
IN SECURITY_INFORMATION SecurityInformation,
|
|
OUT PSECURITY_DESCRIPTOR ResultantDescriptor,
|
|
IN ULONG DescriptorLength,
|
|
OUT PULONG ReturnLength)
|
|
{
|
|
NTSTATUS Status;
|
|
SECURITY_DESCRIPTOR desc;
|
|
BOOLEAN defaulted, present;
|
|
PACL pacl;
|
|
PSID psid;
|
|
|
|
Status = RtlCreateSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION);
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
if (SecurityInformation & OWNER_SECURITY_INFORMATION)
|
|
{
|
|
Status = RtlGetOwnerSecurityDescriptor(ObjectDescriptor, &psid, &defaulted);
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
Status = RtlSetOwnerSecurityDescriptor(&desc, psid, defaulted);
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
}
|
|
|
|
if (SecurityInformation & GROUP_SECURITY_INFORMATION)
|
|
{
|
|
Status = RtlGetGroupSecurityDescriptor(ObjectDescriptor, &psid, &defaulted);
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
Status = RtlSetGroupSecurityDescriptor(&desc, psid, defaulted);
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
}
|
|
|
|
if (SecurityInformation & DACL_SECURITY_INFORMATION)
|
|
{
|
|
Status = RtlGetDaclSecurityDescriptor(ObjectDescriptor, &present, &pacl, &defaulted);
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
Status = RtlSetDaclSecurityDescriptor(&desc, present, pacl, defaulted);
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
}
|
|
|
|
if (SecurityInformation & SACL_SECURITY_INFORMATION)
|
|
{
|
|
Status = RtlGetSaclSecurityDescriptor(ObjectDescriptor, &present, &pacl, &defaulted);
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
Status = RtlSetSaclSecurityDescriptor(&desc, present, pacl, defaulted);
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
}
|
|
|
|
*ReturnLength = DescriptorLength;
|
|
return RtlAbsoluteToSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
|
|
}
|
|
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlSetSecurityObject(IN SECURITY_INFORMATION SecurityInformation,
|
|
IN PSECURITY_DESCRIPTOR ModificationDescriptor,
|
|
OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
|
|
IN PGENERIC_MAPPING GenericMapping,
|
|
IN HANDLE Token)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlRegisterSecureMemoryCacheCallback(IN PRTL_SECURE_MEMORY_CACHE_CALLBACK Callback)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
BOOLEAN
|
|
NTAPI
|
|
RtlFlushSecureMemoryCache(IN PVOID MemoryCache,
|
|
IN OPTIONAL SIZE_T MemoryLength)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|