[RTL]: Implement and half-plement the Object Security APIs. In most cases, ultimately forward to an internal (unimplemented) worker function, but some APIs were implemented fully. Also add missing RtlCreateAndSetSD and export it (unimplemented).

svn path=/trunk/; revision=57482
This commit is contained in:
Alex Ionescu 2012-10-04 19:32:18 +00:00
parent 3e8f4222f0
commit 61d7f64ce7
2 changed files with 302 additions and 59 deletions

View file

@ -508,7 +508,7 @@
@ stdcall RtlCopyUnicodeString(ptr ptr)
@ stdcall RtlCreateAcl(ptr long long)
@ stdcall RtlCreateActivationContext(ptr ptr)
;@ stdcall RtlCreateAndSetSD
@ stdcall RtlCreateAndSetSD(ptr long ptr ptr ptr)
@ stdcall RtlCreateAtomTable(long ptr)
@ stdcall RtlCreateBootStatusDataFile()
@ stdcall RtlCreateEnvironment(long ptr)

View file

@ -9,11 +9,71 @@
/* INCLUDES *****************************************************************/
#include <rtl.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ***************************************************************/
/* PRIVATE FUNCTIONS **********************************************************/
NTSTATUS
NTAPI
RtlpSetSecurityObject(IN PVOID Object,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR ModificationDescriptor,
OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
IN ULONG AutoInheritFlags,
IN ULONG PoolType,
IN PGENERIC_MAPPING GenericMapping,
IN HANDLE Token OPTIONAL)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
RtlpNewSecurityObject(IN PSECURITY_DESCRIPTOR ParentDescriptor,
IN PSECURITY_DESCRIPTOR CreatorDescriptor,
OUT PSECURITY_DESCRIPTOR *NewDescriptor,
IN LPGUID *ObjectTypes,
IN ULONG GuidCount,
IN BOOLEAN IsDirectoryObject,
IN ULONG AutoInheritFlags,
IN HANDLE Token,
IN PGENERIC_MAPPING GenericMapping)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
RtlpConvertToAutoInheritSecurityObject(IN PSECURITY_DESCRIPTOR ParentDescriptor,
IN PSECURITY_DESCRIPTOR CreatorDescriptor,
OUT PSECURITY_DESCRIPTOR *NewDescriptor,
IN LPGUID ObjectType,
IN BOOLEAN IsDirectoryObject,
IN PGENERIC_MAPPING GenericMapping)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*
* @unimplemented
*/
NTSTATUS
NTAPI
RtlCreateAndSetSD(IN PVOID AceData,
IN ULONG AceCount,
IN PSID OwnerSid OPTIONAL,
IN PSID GroupSid OPTIONAL,
OUT PSECURITY_DESCRIPTOR *NewDescriptor)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @implemented
@ -22,18 +82,15 @@ NTSTATUS
NTAPI
RtlDeleteSecurityObject(IN PSECURITY_DESCRIPTOR *ObjectDescriptor)
{
DPRINT("RtlDeleteSecurityObject(%p)\n", ObjectDescriptor);
RtlFreeHeap(RtlGetProcessHeap(),
0,
*ObjectDescriptor);
DPRINT1("RtlDeleteSecurityObject(%p)\n", ObjectDescriptor);
/* Free the object from the heap */
RtlFreeHeap(RtlGetProcessHeap(), 0, *ObjectDescriptor);
return STATUS_SUCCESS;
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
@ -44,12 +101,22 @@ RtlNewSecurityObject(IN PSECURITY_DESCRIPTOR ParentDescriptor,
IN HANDLE Token,
IN PGENERIC_MAPPING GenericMapping)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
DPRINT1("RtlNewSecurityObject(%p)\n", ParentDescriptor);
/* Call the internal API */
return RtlpNewSecurityObject(ParentDescriptor,
CreatorDescriptor,
NewDescriptor,
NULL,
0,
IsDirectoryObject,
0,
Token,
GenericMapping);
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
@ -62,12 +129,22 @@ RtlNewSecurityObjectEx(IN PSECURITY_DESCRIPTOR ParentDescriptor,
IN HANDLE Token,
IN PGENERIC_MAPPING GenericMapping)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
DPRINT1("RtlNewSecurityObjectEx(%p)\n", ParentDescriptor);
/* Call the internal API */
return RtlpNewSecurityObject(ParentDescriptor,
CreatorDescriptor,
NewDescriptor,
ObjectType ? &ObjectType : NULL,
ObjectType ? 1 : 0,
IsDirectoryObject,
AutoInheritFlags,
Token,
GenericMapping);
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
@ -81,28 +158,75 @@ RtlNewSecurityObjectWithMultipleInheritance(IN PSECURITY_DESCRIPTOR ParentDescri
IN HANDLE Token,
IN PGENERIC_MAPPING GenericMapping)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
DPRINT1("RtlNewSecurityObjectWithMultipleInheritance(%p)\n", ParentDescriptor);
/* Call the internal API */
return RtlpNewSecurityObject(ParentDescriptor,
CreatorDescriptor,
NewDescriptor,
ObjectTypes,
GuidCount,
IsDirectoryObject,
AutoInheritFlags,
Token,
GenericMapping);
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
RtlConvertToAutoInheritSecurityObject(IN PSECURITY_DESCRIPTOR ParentDescriptor,
IN PSECURITY_DESCRIPTOR CreatorDescriptor,
OUT PSECURITY_DESCRIPTOR *NewDescriptor,
IN LPGUID ObjectType,
IN BOOLEAN IsDirectoryObject,
IN PGENERIC_MAPPING GenericMapping)
RtlNewInstanceSecurityObject(IN BOOLEAN ParentDescriptorChanged,
IN BOOLEAN CreatorDescriptorChanged,
IN PLUID OldClientTokenModifiedId,
OUT PLUID NewClientTokenModifiedId,
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;
TOKEN_STATISTICS TokenStats;
ULONG Size;
NTSTATUS Status;
DPRINT1("RtlNewInstanceSecurityObject(%p)\n", ParentDescriptor);
/* Query the token statistics */
Status = NtQueryInformationToken(Token,
TokenStatistics,
&TokenStats,
sizeof(TokenStats),
&Size);
if (!NT_SUCCESS(Status)) return Status;
/* Return the LUID */
*NewClientTokenModifiedId = TokenStats.ModifiedId;
/* Check if the LUID changed */
if (RtlEqualLuid(NewClientTokenModifiedId, OldClientTokenModifiedId))
{
/* Did nothing change? */
if (!(ParentDescriptorChanged) && !(CreatorDescriptorChanged))
{
/* There's no new descriptor, we're done */
*NewDescriptor = NULL;
return STATUS_SUCCESS;
}
}
/* Call the standard API */
return RtlNewSecurityObject(ParentDescriptor,
CreatorDescriptor,
NewDescriptor,
IsDirectoryObject,
Token,
GenericMapping);
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
@ -114,32 +238,42 @@ RtlCreateUserSecurityObject(IN PVOID AceData,
IN PGENERIC_MAPPING GenericMapping,
OUT PSECURITY_DESCRIPTOR *NewDescriptor)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status;
PSECURITY_DESCRIPTOR Sd;
HANDLE TokenHandle;
DPRINT1("RtlCreateUserSecurityObject(%p)\n", AceData);
/* Create the security descriptor based on the ACE Data */
Status = RtlCreateAndSetSD(AceData,
AceCount,
OwnerSid,
GroupSid,
&Sd);
if (!NT_SUCCESS(Status)) return Status;
/* Open the process token */
Status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY, &TokenHandle);
if (!NT_SUCCESS(Status)) goto Quickie;
/* Create the security object */
Status = RtlNewSecurityObject(NULL,
Sd,
NewDescriptor,
IsDirectoryObject,
TokenHandle,
GenericMapping);
/* We're done, close the token handle */
NtClose(TokenHandle);
Quickie:
/* Free the SD and return status */
RtlFreeHeap(RtlGetProcessHeap(), 0, Sd);
return Status;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
RtlNewInstanceSecurityObject(IN BOOLEAN ParentDescriptorChanged,
IN BOOLEAN CreatorDescriptorChanged,
IN PLUID OldClientTokenModifiedI,
OUT PLUID NewClientTokenModifiedId,
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
* @implemented
*/
NTSTATUS
NTAPI
@ -150,8 +284,81 @@ RtlNewSecurityGrantedAccess(IN ACCESS_MASK DesiredAccess,
IN PGENERIC_MAPPING GenericMapping,
OUT PACCESS_MASK RemainingDesiredAccess)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status;
BOOLEAN Granted, CallerToken;
TOKEN_STATISTICS TokenStats;
ULONG Size;
DPRINT1("RtlNewSecurityGrantedAccess(%p)\n", DesiredAccess);
/* Has the caller passed a token? */
if (!Token)
{
/* Remember that we'll have to close the handle */
CallerToken = FALSE;
/* Nope, open it */
Status = NtOpenThreadToken(NtCurrentThread(), TOKEN_QUERY, TRUE, &Token);
if (!NT_SUCCESS(Status)) return Status;
}
else
{
/* Yep, use it */
CallerToken = TRUE;
}
/* Get information on the token */
Status = NtQueryInformationToken(Token,
TokenStatistics,
&TokenStats,
sizeof(TokenStats),
&Size);
ASSERT(NT_SUCCESS(Status));
/* Windows doesn't do anything with the token statistics! */
/* Map the access and return it back decoded */
RtlMapGenericMask(&DesiredAccess, GenericMapping);
*RemainingDesiredAccess = DesiredAccess;
/* Check if one of the rights requested was the SACL right */
if (DesiredAccess & ACCESS_SYSTEM_SECURITY)
{
/* Pretend that it's allowed FIXME: Do privilege check */
DPRINT1("Missing privilege check for SE_SECURITY_PRIVILEGE");
Granted = TRUE;
*RemainingDesiredAccess &= ~ACCESS_SYSTEM_SECURITY;
}
else
{
/* Nothing to grant */
Granted = FALSE;
}
/* If the caller did not pass in a token, close the handle to ours */
if (!CallerToken) NtClose(Token);
/* We need space to return only 1 privilege -- already part of the struct */
Size = sizeof(PRIVILEGE_SET);
if (Size > *Length)
{
/* Tell the caller how much space we need and fail */
*Length = Size;
return STATUS_BUFFER_TOO_SMALL;
}
/* Check if the SACL right was granted... */
RtlZeroMemory(&Privileges, Size);
if (Granted)
{
/* Yes, return it in the structure */
Privileges->PrivilegeCount = 1;
Privileges->Privilege[0].Luid.LowPart = SE_SECURITY_PRIVILEGE;
Privileges->Privilege[0].Luid.HighPart = 0;
Privileges->Privilege[0].Attributes = SE_PRIVILEGE_USED_FOR_ACCESS;
}
/* All done */
return STATUS_SUCCESS;
}
/*
@ -212,7 +419,7 @@ RtlQuerySecurityObject(IN PSECURITY_DESCRIPTOR ObjectDescriptor,
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
@ -222,12 +429,19 @@ RtlSetSecurityObject(IN SECURITY_INFORMATION SecurityInformation,
IN PGENERIC_MAPPING GenericMapping,
IN HANDLE Token)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
/* Call the internal API */
return RtlpSetSecurityObject(NULL,
SecurityInformation,
ModificationDescriptor,
ObjectsSecurityDescriptor,
0,
PagedPool,
GenericMapping,
Token);
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
@ -238,8 +452,37 @@ RtlSetSecurityObjectEx(IN SECURITY_INFORMATION SecurityInformation,
IN PGENERIC_MAPPING GenericMapping,
IN HANDLE Token)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
/* Call the internal API */
return RtlpSetSecurityObject(NULL,
SecurityInformation,
ModificationDescriptor,
ObjectsSecurityDescriptor,
AutoInheritFlags,
PagedPool,
GenericMapping,
Token);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
RtlConvertToAutoInheritSecurityObject(IN PSECURITY_DESCRIPTOR ParentDescriptor,
IN PSECURITY_DESCRIPTOR CreatorDescriptor,
OUT PSECURITY_DESCRIPTOR *NewDescriptor,
IN LPGUID ObjectType,
IN BOOLEAN IsDirectoryObject,
IN PGENERIC_MAPPING GenericMapping)
{
/* Call the internal API */
return RtlpConvertToAutoInheritSecurityObject(ParentDescriptor,
CreatorDescriptor,
NewDescriptor,
ObjectType,
IsDirectoryObject,
GenericMapping);
}
/*