Author: ion
Date: Thu Oct 4 19:32:18 2012
New Revision: 57482
URL:
http://svn.reactos.org/svn/reactos?rev=57482&view=rev
Log:
[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).
Modified:
trunk/reactos/dll/ntdll/def/ntdll.spec
trunk/reactos/lib/rtl/security.c
Modified: trunk/reactos/dll/ntdll/def/ntdll.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/def/ntdll.spec?r…
==============================================================================
--- trunk/reactos/dll/ntdll/def/ntdll.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/def/ntdll.spec [iso-8859-1] Thu Oct 4 19:32:18 2012
@@ -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)
Modified: trunk/reactos/lib/rtl/security.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/security.c?rev=574…
==============================================================================
--- trunk/reactos/lib/rtl/security.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/security.c [iso-8859-1] Thu Oct 4 19:32:18 2012
@@ -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 @@
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 @@
IN HANDLE Token,
IN PGENERIC_MAPPING GenericMapping)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
+ DPRINT1("RtlNewSecurityObject(%p)\n", ParentDescriptor);
+
+ /* Call the internal API */
+ return RtlpNewSecurityObject(ParentDescriptor,
+ CreatorDescriptor,
+ NewDescriptor,
+ NULL,
+ 0,
+ IsDirectoryObject,
+ 0,
+ Token,
+ GenericMapping);
+}
+
+/*
+ * @implemented
*/
NTSTATUS
NTAPI
@@ -62,12 +129,22 @@
IN HANDLE Token,
IN PGENERIC_MAPPING GenericMapping)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
+ DPRINT1("RtlNewSecurityObjectEx(%p)\n", ParentDescriptor);
+
+ /* Call the internal API */
+ return RtlpNewSecurityObject(ParentDescriptor,
+ CreatorDescriptor,
+ NewDescriptor,
+ ObjectType ? &ObjectType : NULL,
+ ObjectType ? 1 : 0,
+ IsDirectoryObject,
+ AutoInheritFlags,
+ Token,
+ GenericMapping);
+}
+
+/*
+ * @implemented
*/
NTSTATUS
NTAPI
@@ -81,28 +158,75 @@
IN HANDLE Token,
IN PGENERIC_MAPPING GenericMapping)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-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)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
+ DPRINT1("RtlNewSecurityObjectWithMultipleInheritance(%p)\n",
ParentDescriptor);
+
+ /* Call the internal API */
+ return RtlpNewSecurityObject(ParentDescriptor,
+ CreatorDescriptor,
+ NewDescriptor,
+ ObjectTypes,
+ GuidCount,
+ IsDirectoryObject,
+ AutoInheritFlags,
+ Token,
+ GenericMapping);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+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)
+{
+ 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);
+}
+
+/*
+ * @implemented
*/
NTSTATUS
NTAPI
@@ -114,32 +238,42 @@
IN PGENERIC_MAPPING GenericMapping,
OUT PSECURITY_DESCRIPTOR *NewDescriptor)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @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
+ 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;
+}
+
+/*
+ * @implemented
*/
NTSTATUS
NTAPI
@@ -150,8 +284,81 @@
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 @@
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
@@ -222,12 +429,19 @@
IN PGENERIC_MAPPING GenericMapping,
IN HANDLE Token)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
+ /* Call the internal API */
+ return RtlpSetSecurityObject(NULL,
+ SecurityInformation,
+ ModificationDescriptor,
+ ObjectsSecurityDescriptor,
+ 0,
+ PagedPool,
+ GenericMapping,
+ Token);
+}
+
+/*
+ * @implemented
*/
NTSTATUS
NTAPI
@@ -238,6 +452,46 @@
IN PGENERIC_MAPPING GenericMapping,
IN HANDLE Token)
{
+ /* 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);
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+RtlRegisterSecureMemoryCacheCallback(IN PRTL_SECURE_MEMORY_CACHE_CALLBACK Callback)
+{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
@@ -245,17 +499,6 @@
/*
* @unimplemented
*/
-NTSTATUS
-NTAPI
-RtlRegisterSecureMemoryCacheCallback(IN PRTL_SECURE_MEMORY_CACHE_CALLBACK Callback)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
BOOLEAN
NTAPI
RtlFlushSecureMemoryCache(IN PVOID MemoryCache,