Example #1
0
File: init.c Project: GYGit/reactos
/*++
 * @name CsrCreateLocalSystemSD
 *
 * The CsrCreateLocalSystemSD routine creates a Security Descriptor for
 * the local account with PORT_ALL_ACCESS.
 *
 * @param LocalSystemSd
 *        Pointer to a pointer to the security descriptor to create.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
{
    SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
    PSID SystemSid;
    ULONG Length;
    PSECURITY_DESCRIPTOR SystemSd;
    PACL Dacl;
    NTSTATUS Status;

    /* Initialize the System SID */
    RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
                                SECURITY_LOCAL_SYSTEM_RID,
                                0, 0, 0, 0, 0, 0, 0,
                                &SystemSid);

    /* Get the length of the SID */
    Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);

    /* Allocate a buffer for the Security Descriptor, with SID and DACL */
    SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);

    /* Set the pointer to the DACL */
    Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH);

    /* Now create the SD itself */
    Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status)) goto Quit;

    /* Create the DACL for it */
    RtlCreateAcl(Dacl, Length, ACL_REVISION2);

    /* Create the ACE */
    Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid);
    if (!NT_SUCCESS(Status)) goto Quit;

    /* Clear the DACL in the SD */
    Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE);
    if (!NT_SUCCESS(Status)) goto Quit;

Quit:
    if (!NT_SUCCESS(Status))
    {
        RtlFreeHeap(CsrHeap, 0, SystemSd);
        SystemSd = NULL;
    }

    /* Free the SID and return*/
    RtlFreeSid(SystemSid);
    *LocalSystemSd = SystemSd;
    return Status;
}
Example #2
0
VOID StripPermissions( WCHAR* KeyName )
{
    HANDLE keyHandle;
    unsigned char p[9000];
    PSECURITY_DESCRIPTOR psecdesc = (PSECURITY_DESCRIPTOR)p;
    VOID* selfSecurityDescriptor;
    ULONG bufferLength = 20;

    keyHandle = Registry::OpenKey(KeyName, WRITE_DAC);

    RtlCreateSecurityDescriptor(psecdesc, SECURITY_DESCRIPTOR_REVISION);
    RtlSetDaclSecurityDescriptor(psecdesc, TRUE, NULL, TRUE);

    selfSecurityDescriptor = RtlAllocateHeap(PushHeapHandle, 0, 20);

    RtlMakeSelfRelativeSD(psecdesc, selfSecurityDescriptor, &bufferLength);
    NtSetSecurityObject(keyHandle, DACL_SECURITY_INFORMATION, selfSecurityDescriptor);
    NtClose(keyHandle);
}
Example #3
0
BOOLEAN
ObInitSystem(
    VOID
    )

/*++

Routine Description:

    This function performs the system initialization for the object
    manager.  The object manager data structures are self describing
    with the exception of the root directory, the type object type and
    the directory object type.  The initialization code then constructs
    these objects by hand to get the ball rolling.

Arguments:

    None.

Return Value:

    TRUE if successful and FALSE if an error occurred.

    The following errors can occur:

    - insufficient memory

--*/

{

    USHORT CreateInfoMaxDepth;
    USHORT NameBufferMaxDepth;
    ULONG RegionSegmentSize;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
    UNICODE_STRING TypeTypeName;
    UNICODE_STRING SymbolicLinkTypeName;
    UNICODE_STRING DosDevicesDirectoryName;
    UNICODE_STRING DirectoryTypeName;
    UNICODE_STRING RootDirectoryName;
    UNICODE_STRING TypeDirectoryName;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE RootDirectoryHandle;
    HANDLE TypeDirectoryHandle;
    PLIST_ENTRY Next, Head;
    POBJECT_HEADER ObjectTypeHeader;
    POBJECT_HEADER_CREATOR_INFO CreatorInfo;
    POBJECT_HEADER_NAME_INFO NameInfo;
    MM_SYSTEMSIZE SystemSize;
    SECURITY_DESCRIPTOR AuditSd;
    PSECURITY_DESCRIPTOR EffectiveSd;
    PACL    AuditAllAcl;
    UCHAR   AuditAllBuffer[250];  // Ample room for the ACL
    ULONG   AuditAllLength;
    PACE_HEADER Ace;

    //
    // PHASE 0 Initialization
    //

    if (InitializationPhase == 0) {

        //
        // Determine the the size of the object creation and the name buffer
        // lookaside lists.
        //

        SystemSize = MmQuerySystemSize();
        if (SystemSize == MmLargeSystem) {
            if (MmIsThisAnNtAsSystem()) {
                CreateInfoMaxDepth = 64;
                NameBufferMaxDepth = 32;

            } else {
                CreateInfoMaxDepth = 32;
                NameBufferMaxDepth = 16;
            }

        } else {
            CreateInfoMaxDepth = 3;
            NameBufferMaxDepth = 3;
        }

        //
        // Initialize the object creation lookaside list.
        //

        ExInitializeNPagedLookasideList(&ObpCreateInfoLookasideList,
                                        NULL,
                                        NULL,
                                        0,
                                        sizeof(OBJECT_CREATE_INFORMATION),
                                        'iCbO',
                                        CreateInfoMaxDepth);

        //
        // Initialize the name buffer lookaside list.
        //

        ExInitializeNPagedLookasideList(&ObpNameBufferLookasideList,
                                        NULL,
                                        NULL,
                                        0,
                                        OBJECT_NAME_BUFFER_SIZE,
                                        'mNbO',
                                        NameBufferMaxDepth);

        InitializeListHead( &ObpRemoveObjectQueue );

        //
        // Initialize security descriptor cache
        //

        ObpInitSecurityDescriptorCache();

        KeInitializeMutant( &ObpInitKillMutant, FALSE );
        KeInitializeEvent( &ObpDefaultObject, NotificationEvent, TRUE );
        KeInitializeSpinLock( &ObpLock );
        PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS;
        PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;

        //
        // Initialize the quota block
        //

        KeInitializeSpinLock(&PspDefaultQuotaBlock.QuotaLock);
        PspDefaultQuotaBlock.ReferenceCount = 1;
        PspDefaultQuotaBlock.QuotaPoolLimit[PagedPool] = (ULONG)-1;
        PspDefaultQuotaBlock.QuotaPoolLimit[NonPagedPool] = (ULONG)-1;
        PspDefaultQuotaBlock.PagefileLimit = (ULONG)-1;

        PsGetCurrentProcess()->QuotaBlock = &PspDefaultQuotaBlock;

        PsGetCurrentProcess()->ObjectTable =
            ExCreateHandleTable( NULL,
                                 0,
                                 0
                               );

        RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) );
        ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer );
        ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
        ObjectTypeInitializer.PoolType = NonPagedPool;

        RtlInitUnicodeString( &TypeTypeName, L"Type" );
        ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
        ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
        ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_TYPE );
        ObjectTypeInitializer.MaintainTypeList = TRUE;
        ObjectTypeInitializer.UseDefaultObject = TRUE;
        ObCreateObjectType( &TypeTypeName,
                            &ObjectTypeInitializer,
                            (PSECURITY_DESCRIPTOR)NULL,
                            &ObpTypeObjectType
                          );

        RtlInitUnicodeString( &DirectoryTypeName, L"Directory" );
        ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_DIRECTORY );
        ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
        ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
        ObjectTypeInitializer.MaintainTypeList = FALSE;
        ObCreateObjectType( &DirectoryTypeName,
                            &ObjectTypeInitializer,
                            (PSECURITY_DESCRIPTOR)NULL,
                            &ObpDirectoryObjectType
                          );

        RtlInitUnicodeString( &SymbolicLinkTypeName, L"SymbolicLink" );
        ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_SYMBOLIC_LINK );
        ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS;
        ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping;
        ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink;
        ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink;
        ObCreateObjectType( &SymbolicLinkTypeName,
                            &ObjectTypeInitializer,
                            (PSECURITY_DESCRIPTOR)NULL,
                            &ObpSymbolicLinkObjectType
                          );

        ExInitializeResourceLite( &ObpRootDirectoryMutex );

#if i386 && !FPO
        ObpCurCachedGrantedAccessIndex = 0;
        ObpMaxCachedGrantedAccessIndex = PAGE_SIZE / sizeof( ACCESS_MASK );
        ObpCachedGrantedAccesses = ExAllocatePoolWithTag( NonPagedPool, PAGE_SIZE, 'gAbO' );
#endif // i386 && !FPO

#if DBG
        ObpCreateObjectEventId = RtlCreateEventId( NULL,
                                                   0,
                                                   "CreateObject",
                                                   6,
                                                   RTL_EVENT_ULONG_PARAM, "Object", 0,
                                                   RTL_EVENT_PUNICODE_STRING_PARAM, "Type", 0,
                                                   RTL_EVENT_ULONG_PARAM, "PagedPool", 0,
                                                   RTL_EVENT_ULONG_PARAM, "NonPagedPool", 0,
                                                   RTL_EVENT_PUNICODE_STRING_PARAM, "Name", 0,
                                                   RTL_EVENT_FLAGS_PARAM, "", 5,
                                                     OBJ_INHERIT, "Inherit",
                                                     OBJ_PERMANENT, "Permanent",
                                                     OBJ_OPENIF, "OpenIf",
                                                     OBJ_CASE_INSENSITIVE, "CaseInsenitive",
                                                     OBJ_EXCLUSIVE, "Exclusive"
                                                 );
        ObpFreeObjectEventId = RtlCreateEventId( NULL,
                                                 0,
                                                 "FreeObject",
                                                 3,
                                                 RTL_EVENT_ULONG_PARAM, "Object", 0,
                                                 RTL_EVENT_ULONG_PARAM, "Type", 0,
                                                 RTL_EVENT_PUNICODE_STRING_PARAM, "Name", 0
                                               );
#endif // DBG

        }             // End of Phase 0 Initializtion


    //
    // PHASE 1 Initialization
    //

    if (InitializationPhase == 1) {


        EffectiveSd = SePublicDefaultSd;

        //
        // This code is only executed if base auditing is turned on.
        //

        if ((ObpAuditBaseDirectories != 0) || (ObpAuditBaseObjects != 0)) {

            //
            // build an SACL to audit
            //
            AuditAllAcl = (PACL)AuditAllBuffer;
            AuditAllLength = (ULONG)sizeof(ACL) +
                               ((ULONG)sizeof(SYSTEM_AUDIT_ACE)) +
                               SeLengthSid(SeWorldSid);
            ASSERT( sizeof(AuditAllBuffer)   >   AuditAllLength );
            Status = RtlCreateAcl( AuditAllAcl, AuditAllLength, ACL_REVISION2);
            ASSERT( NT_SUCCESS(Status) );
            Status = RtlAddAuditAccessAce (
                         AuditAllAcl,
                         ACL_REVISION2,
                         GENERIC_ALL,
                         SeWorldSid,
                         TRUE,  TRUE        //Audit success and failure
                         );
            ASSERT( NT_SUCCESS(Status) );

            Status = RtlGetAce( AuditAllAcl, 0,  (PVOID)&Ace );
            ASSERT( NT_SUCCESS(Status) );

            if (ObpAuditBaseDirectories != 0) {
                Ace->AceFlags |= (CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
                }

            if (ObpAuditBaseObjects != 0) {
                Ace->AceFlags |= (OBJECT_INHERIT_ACE    |
                                  CONTAINER_INHERIT_ACE |
                                  INHERIT_ONLY_ACE);
                }



            //
            // Now create a security descriptor that looks just like
            // the public default, but has auditing in it as well.

            EffectiveSd = (PSECURITY_DESCRIPTOR)&AuditSd;
            Status = RtlCreateSecurityDescriptor( EffectiveSd,
                                                  SECURITY_DESCRIPTOR_REVISION1 );
            ASSERT( NT_SUCCESS(Status) );

            Status = RtlSetDaclSecurityDescriptor( EffectiveSd,
                                                   TRUE,        // DaclPresent
                                                   SePublicDefaultDacl,
                                                   FALSE        // DaclDefaulted
                                                   );
            ASSERT( NT_SUCCESS(Status) );
            Status = RtlSetSaclSecurityDescriptor( EffectiveSd,
                                                   TRUE,        // DaclPresent
                                                   AuditAllAcl,
                                                   FALSE        // DaclDefaulted
                                                   );
            ASSERT( NT_SUCCESS(Status) );
            }


        //
        // We only need to use the EffectiveSd on the root.  The SACL
        // will be inherited by all other objects.
        //

        RtlInitUnicodeString( &RootDirectoryName, L"\\" );
        InitializeObjectAttributes( &ObjectAttributes,
                                    &RootDirectoryName,
                                    OBJ_CASE_INSENSITIVE |
                                    OBJ_PERMANENT,
                                    NULL,
                                    EffectiveSd
                                  );
        Status = NtCreateDirectoryObject( &RootDirectoryHandle,
                                          DIRECTORY_ALL_ACCESS,
                                          &ObjectAttributes
                                        );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = ObReferenceObjectByHandle( RootDirectoryHandle,
                                            0,
                                            ObpDirectoryObjectType,
                                            KernelMode,
                                            (PVOID *)&ObpRootDirectoryObject,
                                            NULL
                                          );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = NtClose( RootDirectoryHandle );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        RtlInitUnicodeString( &TypeDirectoryName, L"\\ObjectTypes" );
        InitializeObjectAttributes( &ObjectAttributes,
                                    &TypeDirectoryName,
                                    OBJ_CASE_INSENSITIVE |
                                    OBJ_PERMANENT,
                                    NULL,
                                    NULL
                                  );
        Status = NtCreateDirectoryObject( &TypeDirectoryHandle,
                                          DIRECTORY_ALL_ACCESS,
                                          &ObjectAttributes
                                        );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = ObReferenceObjectByHandle( TypeDirectoryHandle,
                                            0,
                                            ObpDirectoryObjectType,
                                            KernelMode,
                                            (PVOID *)&ObpTypeDirectoryObject,
                                            NULL
                                          );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = NtClose( TypeDirectoryHandle );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        ObpEnterRootDirectoryMutex();

        Head = &ObpTypeObjectType->TypeList;
        Next = Head->Flink;
        while (Next != Head) {
            CreatorInfo = CONTAINING_RECORD( Next,
                                             OBJECT_HEADER_CREATOR_INFO,
                                             TypeList
                                           );
            ObjectTypeHeader = (POBJECT_HEADER)(CreatorInfo+1);
            NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectTypeHeader );
            if (NameInfo != NULL && NameInfo->Directory == NULL) {
                if (!ObpLookupDirectoryEntry( ObpTypeDirectoryObject,
                                              &NameInfo->Name,
                                              OBJ_CASE_INSENSITIVE
                                            )
                   ) {
                    ObpInsertDirectoryEntry( ObpTypeDirectoryObject,
                                             &ObjectTypeHeader->Body
                                           );
                    }
                }

            Next = Next->Flink;
            }

        ObpLeaveRootDirectoryMutex();

        //
        // Create \DosDevices object directory for drive letters and Win32 device names
        //
        Status = ObpCreateDosDevicesDirectory();
        if (!NT_SUCCESS( Status )) {
            return FALSE;
            }
        }

    return TRUE;
}
Example #4
0
/******************************************************************************
 *  NtQuerySecurityObject	[NTDLL.@]
 *
 * analogue to GetKernelObjectSecurity
 *
 * NOTES
 *  only the lowest 4 bit of SecurityObjectInformationClass are used
 *  0x7-0xf returns STATUS_ACCESS_DENIED (even running with system privileges)
 *
 * FIXME: we are constructing a fake sid
 *  (Administrators:Full, System:Full, Everyone:Read)
 */
NTSTATUS WINAPI
NtQuerySecurityObject(
	IN HANDLE Object,
	IN SECURITY_INFORMATION RequestedInformation,
	OUT PSECURITY_DESCRIPTOR pSecurityDesriptor,
	IN ULONG Length,
	OUT PULONG ResultLength)
{
	static SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
	static SID_IDENTIFIER_AUTHORITY worldSidAuthority = {SECURITY_WORLD_SID_AUTHORITY};
	BYTE Buffer[256];
	PISECURITY_DESCRIPTOR_RELATIVE psd = (PISECURITY_DESCRIPTOR_RELATIVE)Buffer;
	UINT BufferIndex = sizeof(SECURITY_DESCRIPTOR_RELATIVE);

	FIXME("(0x%08x,0x%08lx,%p,0x%08lx,%p) stub!\n",
	Object, RequestedInformation, pSecurityDesriptor, Length, ResultLength);

	RequestedInformation &= 0x0000000f;

	if (RequestedInformation & SACL_SECURITY_INFORMATION) return STATUS_ACCESS_DENIED;

	ZeroMemory(Buffer, 256);
	RtlCreateSecurityDescriptor((PSECURITY_DESCRIPTOR)psd, SECURITY_DESCRIPTOR_REVISION);
	psd->Control = SE_SELF_RELATIVE |
	  ((RequestedInformation & DACL_SECURITY_INFORMATION) ? SE_DACL_PRESENT:0);

	/* owner: administrator S-1-5-20-220*/
	if (OWNER_SECURITY_INFORMATION & RequestedInformation)
	{
	  PSID psid = (PSID)&(Buffer[BufferIndex]);

	  psd->Owner = BufferIndex;
	  BufferIndex += RtlLengthRequiredSid(2);

	  psid->Revision = SID_REVISION;
	  psid->SubAuthorityCount = 2;
	  psid->IdentifierAuthority = localSidAuthority;
	  psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
	  psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS;
	}

	/* group: built in domain S-1-5-12 */
	if (GROUP_SECURITY_INFORMATION & RequestedInformation)
	{
	  PSID psid = (PSID) &(Buffer[BufferIndex]);

	  psd->Group = BufferIndex;
	  BufferIndex += RtlLengthRequiredSid(1);

	  psid->Revision = SID_REVISION;
	  psid->SubAuthorityCount = 1;
	  psid->IdentifierAuthority = localSidAuthority;
	  psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
	}

	/* discretionary ACL */
	if (DACL_SECURITY_INFORMATION & RequestedInformation)
	{
	  /* acl header */
	  PACL pacl = (PACL)&(Buffer[BufferIndex]);
	  PACCESS_ALLOWED_ACE pace;
	  PSID psid;

	  psd->Dacl = BufferIndex;

	  pacl->AclRevision = MIN_ACL_REVISION;
	  pacl->AceCount = 3;
	  pacl->AclSize = BufferIndex; /* storing the start index temporary */

	  BufferIndex += sizeof(ACL);

	  /* ACE System - full access */
	  pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
	  BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);

	  pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
	  pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
	  pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1);
	  pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER  | 0x3f;
	  pace->SidStart = BufferIndex;

	  /* SID S-1-5-12 (System) */
	  psid = (PSID)&(Buffer[BufferIndex]);

	  BufferIndex += RtlLengthRequiredSid(1);

	  psid->Revision = SID_REVISION;
	  psid->SubAuthorityCount = 1;
	  psid->IdentifierAuthority = localSidAuthority;
	  psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;

	  /* ACE Administrators - full access*/
	  pace = (PACCESS_ALLOWED_ACE) &(Buffer[BufferIndex]);
	  BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);

	  pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
	  pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
	  pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(2);
	  pace->Mask = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER  | 0x3f;
	  pace->SidStart = BufferIndex;

	  /* S-1-5-12 (Administrators) */
	  psid = (PSID)&(Buffer[BufferIndex]);

	  BufferIndex += RtlLengthRequiredSid(2);

	  psid->Revision = SID_REVISION;
	  psid->SubAuthorityCount = 2;
	  psid->IdentifierAuthority = localSidAuthority;
	  psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
	  psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS;

	  /* ACE Everyone - read access */
	  pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]);
	  BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD);

	  pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
	  pace->Header.AceFlags = CONTAINER_INHERIT_ACE;
	  pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1);
	  pace->Mask = READ_CONTROL| 0x19;
	  pace->SidStart = BufferIndex;

	  /* SID S-1-1-0 (Everyone) */
	  psid = (PSID)&(Buffer[BufferIndex]);

	  BufferIndex += RtlLengthRequiredSid(1);

	  psid->Revision = SID_REVISION;
	  psid->SubAuthorityCount = 1;
	  psid->IdentifierAuthority = worldSidAuthority;
	  psid->SubAuthority[0] = 0;

	  /* calculate used bytes */
	  pacl->AclSize = BufferIndex - pacl->AclSize;
	}
	*ResultLength = BufferIndex;
	TRACE("len=%lu\n", *ResultLength);
	if (Length < *ResultLength) return STATUS_BUFFER_TOO_SMALL;
	memcpy(pSecurityDesriptor, Buffer, *ResultLength);

	return STATUS_SUCCESS;
}
Example #5
0
NTSTATUS
ObpGetDosDevicesProtection(
    PSECURITY_DESCRIPTOR SecurityDescriptor
    )

/*++

Routine Description:

    This routine builds a security descriptor for use in creating
    the \DosDevices object directory.  The protection of \DosDevices
    must establish inheritable protection which will dictate how
    dos devices created via the DefineDosDevice() and
    IoCreateUnprotectedSymbolicLink() apis can be managed.

    The protection assigned is dependent upon an administrable registry
    key:

        Key: \hkey_local_machine\System\CurrentControlSet\Control\Session Manager
        Value: [REG_DWORD] ProtectionMode

    If this value is 0x1, then

            Administrators may control all Dos devices,
            Anyone may create new Dos devices (such as net drives
                or additional printers),
            Anyone may use any Dos device,
            The creator of a Dos device may delete it.
            Note that this protects system-defined LPTs and COMs so that only
                administrators may redirect them.  However, anyone may add
                additional printers and direct them to wherever they would
                like.

           This is achieved with the following protection for the DosDevices
           Directory object:

                    Grant:  World:   Execute | Read | Write (No Inherit)
                    Grant:  System:  All Access             (No Inherit)
                    Grant:  World:   Execute                (Inherit Only)
                    Grant:  Admins:  All Access             (Inherit Only)
                    Grant:  System:  All Access             (Inherit Only)
                    Grant:  Owner:   All Access             (Inherit Only)

    If this value is 0x0, or not present, then

            Administrators may control all Dos devices,
            Anyone may create new Dos devices (such as net drives
                or additional printers),
            Anyone may use any Dos device,
            Anyone may delete Dos devices created with either DefineDosDevice()
                or IoCreateUnprotectedSymbolicLink().  This is how network drives
                and LPTs are created (but not COMs).

           This is achieved with the following protection for the DosDevices
           Directory object:

                    Grant:  World:   Execute | Read | Write (No Inherit)
                    Grant:  System:  All Access             (No Inherit)
                    Grant:  World:   All Access             (Inherit Only)


Arguments:

    SecurityDescriptor - The address of a security descriptor to be
        initialized and filled in.  When this security descriptor is no
        longer needed, you should call ObpFreeDosDevicesProtection() to
        free the protection information.


Return Value:

    Returns one of the following status codes:

        STATUS_SUCCESS - normal, successful completion.

        STATUS_NO_MEMORY - not enough memory


--*/

{
    NTSTATUS Status;
    ULONG aceIndex, aclLength;
    PACL dacl;
    PACE_HEADER ace;
    ACCESS_MASK accessMask;

    UCHAR inheritOnlyFlags = (OBJECT_INHERIT_ACE    |
                              CONTAINER_INHERIT_ACE |
                              INHERIT_ONLY_ACE
                             );

    //
    // NOTE:  This routine expects the value of ObpProtectionMode to have been set
    //

    Status = RtlCreateSecurityDescriptor( SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
    ASSERT( NT_SUCCESS( Status ) );

    if (ObpProtectionMode & 0x00000001) {

        //
        // Dacl:
        //          Grant:  World:   Execute | Read | Write (No Inherit)
        //          Grant:  System:  All Access             (No Inherit)
        //          Grant:  World:   Execute                (Inherit Only)
        //          Grant:  Admins:  All Access             (Inherit Only)
        //          Grant:  System:  All Access             (Inherit Only)
        //          Grant:  Owner:   All Access             (Inherit Only)
        //

        aclLength = sizeof( ACL )                           +
                    6 * sizeof( ACCESS_ALLOWED_ACE )        +
                    (2*RtlLengthSid( SeWorldSid ))          +
                    (2*RtlLengthSid( SeLocalSystemSid ))    +
                    RtlLengthSid( SeAliasAdminsSid )        +
                    RtlLengthSid( SeCreatorOwnerSid );

        dacl = (PACL)ExAllocatePool(PagedPool, aclLength );
        if (dacl == NULL) {
            return STATUS_NO_MEMORY;
        }

        Status = RtlCreateAcl( dacl, aclLength, ACL_REVISION2);
        ASSERT( NT_SUCCESS( Status ) );

        //
        // Non-inheritable ACEs first
        //      World
        //      System
        //

        aceIndex = 0;
        accessMask = (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE);
        Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeWorldSid );
        ASSERT( NT_SUCCESS( Status ) );

        aceIndex++;
        accessMask = (GENERIC_ALL);
        Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeLocalSystemSid );
        ASSERT( NT_SUCCESS( Status ) );

        //
        // Inheritable ACEs at the end of the ACL
        //          World
        //          Admins
        //          System
        //          Owner
        //

        aceIndex++;
        accessMask = (GENERIC_EXECUTE);
        Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeWorldSid );
        ASSERT( NT_SUCCESS( Status ) );
        Status = RtlGetAce( dacl, aceIndex, (PVOID)&ace );
        ASSERT( NT_SUCCESS( Status ) );
        ace->AceFlags |= inheritOnlyFlags;

        aceIndex++;
        accessMask = (GENERIC_ALL);
        Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeAliasAdminsSid );
        ASSERT( NT_SUCCESS( Status ) );
        Status = RtlGetAce( dacl, aceIndex, (PVOID)&ace );
        ASSERT( NT_SUCCESS( Status ) );
        ace->AceFlags |= inheritOnlyFlags;

        aceIndex++;
        accessMask = (GENERIC_ALL);
        Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeLocalSystemSid );
        ASSERT( NT_SUCCESS( Status ) );
        Status = RtlGetAce( dacl, aceIndex, (PVOID)&ace );
        ASSERT( NT_SUCCESS( Status ) );
        ace->AceFlags |= inheritOnlyFlags;

        aceIndex++;
        accessMask = (GENERIC_ALL);
        Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeCreatorOwnerSid );
        ASSERT( NT_SUCCESS( Status ) );
        Status = RtlGetAce( dacl, aceIndex, (PVOID)&ace );
        ASSERT( NT_SUCCESS( Status ) );
        ace->AceFlags |= inheritOnlyFlags;

        Status = RtlSetDaclSecurityDescriptor (
                     SecurityDescriptor,
                     TRUE,                  //DaclPresent,
                     dacl,                  //Dacl
                     FALSE                  //!DaclDefaulted
                     );
        ASSERT( NT_SUCCESS( Status ) );



    } else {

        //
        // DACL:
        //          Grant:  World:   Execute | Read | Write (No Inherit)
        //          Grant:  System:  All Access             (No Inherit)
        //          Grant:  World:   All Access             (Inherit Only)
        //

        aclLength = sizeof( ACL )                           +
                    3 * sizeof( ACCESS_ALLOWED_ACE )        +
                    (2*RtlLengthSid( SeWorldSid ))          +
                    RtlLengthSid( SeLocalSystemSid );

        dacl = (PACL)ExAllocatePool(PagedPool, aclLength );
        if (dacl == NULL) {
            return STATUS_NO_MEMORY;
        }

        Status = RtlCreateAcl( dacl, aclLength, ACL_REVISION2);
        ASSERT( NT_SUCCESS( Status ) );

        //
        // Non-inheritable ACEs first
        //      World
        //      System
        //

        aceIndex = 0;
        accessMask = (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE);
        Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeWorldSid );
        ASSERT( NT_SUCCESS( Status ) );

        aceIndex++;
        accessMask = (GENERIC_ALL);
        Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeLocalSystemSid );
        ASSERT( NT_SUCCESS( Status ) );

        //
        // Inheritable ACEs at the end of the ACL
        //          World
        //

        aceIndex++;
        accessMask = (GENERIC_ALL);
        Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeWorldSid );
        ASSERT( NT_SUCCESS( Status ) );
        Status = RtlGetAce( dacl, aceIndex, (PVOID)&ace );
        ASSERT( NT_SUCCESS( Status ) );
        ace->AceFlags |= inheritOnlyFlags;

        Status = RtlSetDaclSecurityDescriptor (
                     SecurityDescriptor,
                     TRUE,                  //DaclPresent,
                     dacl,                  //Dacl
                     FALSE                  //!DaclDefaulted
                     );
        ASSERT( NT_SUCCESS( Status ) );
    }

    return STATUS_SUCCESS;
}
Example #6
0
BOOLEAN
INIT_FUNCTION
NTAPI
SepInitSDs(VOID)
{
    /* Create PublicDefaultSd */
    SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool,
                                              sizeof(SECURITY_DESCRIPTOR), TAG_SD);
    if (SePublicDefaultSd == NULL)
        return FALSE;

    RtlCreateSecurityDescriptor(SePublicDefaultSd,
                                SECURITY_DESCRIPTOR_REVISION);
    RtlSetDaclSecurityDescriptor(SePublicDefaultSd,
                                 TRUE,
                                 SePublicDefaultDacl,
                                 FALSE);

    /* Create PublicDefaultUnrestrictedSd */
    SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
                                                          sizeof(SECURITY_DESCRIPTOR), TAG_SD);
    if (SePublicDefaultUnrestrictedSd == NULL)
        return FALSE;

    RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd,
                                SECURITY_DESCRIPTOR_REVISION);
    RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd,
                                 TRUE,
                                 SePublicDefaultUnrestrictedDacl,
                                 FALSE);

    /* Create PublicOpenSd */
    SePublicOpenSd = ExAllocatePoolWithTag(PagedPool,
                                           sizeof(SECURITY_DESCRIPTOR), TAG_SD);
    if (SePublicOpenSd == NULL)
        return FALSE;

    RtlCreateSecurityDescriptor(SePublicOpenSd,
                                SECURITY_DESCRIPTOR_REVISION);
    RtlSetDaclSecurityDescriptor(SePublicOpenSd,
                                 TRUE,
                                 SePublicOpenDacl,
                                 FALSE);

    /* Create PublicOpenUnrestrictedSd */
    SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
                                                       sizeof(SECURITY_DESCRIPTOR), TAG_SD);
    if (SePublicOpenUnrestrictedSd == NULL)
        return FALSE;

    RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd,
                                SECURITY_DESCRIPTOR_REVISION);
    RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd,
                                 TRUE,
                                 SePublicOpenUnrestrictedDacl,
                                 FALSE);

    /* Create SystemDefaultSd */
    SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool,
                                              sizeof(SECURITY_DESCRIPTOR), TAG_SD);
    if (SeSystemDefaultSd == NULL)
        return FALSE;

    RtlCreateSecurityDescriptor(SeSystemDefaultSd,
                                SECURITY_DESCRIPTOR_REVISION);
    RtlSetDaclSecurityDescriptor(SeSystemDefaultSd,
                                 TRUE,
                                 SeSystemDefaultDacl,
                                 FALSE);

    /* Create UnrestrictedSd */
    SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
                                             sizeof(SECURITY_DESCRIPTOR), TAG_SD);
    if (SeUnrestrictedSd == NULL)
        return FALSE;

    RtlCreateSecurityDescriptor(SeUnrestrictedSd,
                                SECURITY_DESCRIPTOR_REVISION);
    RtlSetDaclSecurityDescriptor(SeUnrestrictedSd,
                                 TRUE,
                                 SeUnrestrictedDacl,
                                 FALSE);

    return TRUE;
}
Example #7
0
NTSTATUS PhSvcApiPortInitialization(
    _In_ PUNICODE_STRING PortName
    )
{
    static SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;

    NTSTATUS status;
    OBJECT_ATTRIBUTES objectAttributes;
    PSECURITY_DESCRIPTOR securityDescriptor;
    ULONG sdAllocationLength;
    UCHAR administratorsSidBuffer[FIELD_OFFSET(SID, SubAuthority) + sizeof(ULONG) * 2];
    PSID administratorsSid;
    PACL dacl;
    ULONG i;

    // Create the API port.

    administratorsSid = (PSID)administratorsSidBuffer;
    RtlInitializeSid(administratorsSid, &ntAuthority, 2);
    *RtlSubAuthoritySid(administratorsSid, 0) = SECURITY_BUILTIN_DOMAIN_RID;
    *RtlSubAuthoritySid(administratorsSid, 1) = DOMAIN_ALIAS_RID_ADMINS;

    sdAllocationLength = SECURITY_DESCRIPTOR_MIN_LENGTH +
        (ULONG)sizeof(ACL) +
        (ULONG)sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(administratorsSid) +
        (ULONG)sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(&PhSeEveryoneSid);

    securityDescriptor = PhAllocate(sdAllocationLength);
    dacl = (PACL)PTR_ADD_OFFSET(securityDescriptor, SECURITY_DESCRIPTOR_MIN_LENGTH);

    RtlCreateSecurityDescriptor(securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
    RtlCreateAcl(dacl, sdAllocationLength - SECURITY_DESCRIPTOR_MIN_LENGTH, ACL_REVISION);
    RtlAddAccessAllowedAce(dacl, ACL_REVISION, PORT_ALL_ACCESS, administratorsSid);
    RtlAddAccessAllowedAce(dacl, ACL_REVISION, PORT_CONNECT, &PhSeEveryoneSid);
    RtlSetDaclSecurityDescriptor(securityDescriptor, TRUE, dacl, FALSE);

    InitializeObjectAttributes(
        &objectAttributes,
        PortName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        securityDescriptor
        );

    status = NtCreatePort(
        &PhSvcApiPortHandle,
        &objectAttributes,
        sizeof(PHSVC_API_CONNECTINFO),
        PhIsExecutingInWow64() ? sizeof(PHSVC_API_MSG64) : sizeof(PHSVC_API_MSG),
        0
        );
    PhFree(securityDescriptor);

    if (!NT_SUCCESS(status))
        return status;

    // Start the API threads.

    PhSvcApiThreadContextTlsIndex = TlsAlloc();

    for (i = 0; i < 2; i++)
    {
        PhCreateThread2(PhSvcApiRequestThreadStart, NULL);
    }

    return status;
}
Example #8
0
static NTSTATUS
RtlpSysVolTakeOwnership(IN PUNICODE_STRING DirectoryPath,
                        IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
    TOKEN_PRIVILEGES TokenPrivileges;
    OBJECT_ATTRIBUTES ObjectAttributes;
    SECURITY_DESCRIPTOR AbsSD;
    PSID AdminSid = NULL;
    IO_STATUS_BLOCK IoStatusBlock;
    BOOLEAN TokenEnabled = FALSE;
    HANDLE hToken = NULL;
    HANDLE hDirectory = NULL;
    NTSTATUS Status;
    ULONG ReturnLength;

    Status = ZwOpenProcessToken(NtCurrentProcess(),
                                TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
                                &hToken);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* attempt to enable the SE_TAKE_OWNERSHIP_PRIVILEGE privilege */
    TokenPrivileges.PrivilegeCount = 1;
    TokenPrivileges.Privileges[0].Luid.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE;
    TokenPrivileges.Privileges[0].Luid.HighPart = 0;
    TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    Status = ZwAdjustPrivilegesToken(hToken,
                                     FALSE,
                                     &TokenPrivileges,
                                     sizeof(TokenPrivileges),
                                     &TokenPrivileges,
                                     &ReturnLength);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }
    TokenEnabled = (TokenPrivileges.PrivilegeCount != 0);

    /* open the directory */
    InitializeObjectAttributes(&ObjectAttributes,
                               DirectoryPath,
                               0,
                               NULL,
                               SecurityDescriptor);

    Status = ZwOpenFile(&hDirectory,
                        SYNCHRONIZE | WRITE_OWNER,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* create the Administrators SID */
    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
                                         2,
                                         SECURITY_BUILTIN_DOMAIN_RID,
                                         DOMAIN_ALIAS_RID_ADMINS,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         &AdminSid);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* create the security descriptor */
    Status = RtlCreateSecurityDescriptor(&AbsSD,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlSetOwnerSecurityDescriptor(&AbsSD,
                                           AdminSid,
                                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* attempt to take ownership */
    Status = ZwSetSecurityObject(hDirectory,
                                 OWNER_SECURITY_INFORMATION,
                                 &AbsSD);

Cleanup:
    if (TokenEnabled)
    {
        ZwAdjustPrivilegesToken(hToken,
                                FALSE,
                                &TokenPrivileges,
                                0,
                                NULL,
                                NULL);
    }

    if (AdminSid != NULL)
    {
        RtlFreeSid(AdminSid);
    }

    if (hDirectory != NULL)
    {
        ZwClose(hDirectory);
    }

    if (hToken != NULL)
    {
        ZwClose(hToken);
    }

    return Status;
}
Example #9
0
File: init.c Project: GYGit/reactos
/*++
 * @name CsrSetProcessSecurity
 *
 * The CsrSetProcessSecurity routine protects access to the CSRSS process
 * from unauthorized tampering.
 *
 * @param None.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrSetProcessSecurity(VOID)
{
    NTSTATUS Status;
    HANDLE hToken, hProcess = NtCurrentProcess();
    ULONG Length;
    PTOKEN_USER TokenInfo = NULL;
    PSECURITY_DESCRIPTOR ProcSd = NULL;
    PACL Dacl;
    PSID UserSid;

    /* Open our token */
    Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Get the Token User Length */
    NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length);

    /* Allocate space for it */
    TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
    if (!TokenInfo)
    {
        Status = STATUS_NO_MEMORY;
        goto Quickie;
    }

    /* Now query the data */
    Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length);
    NtClose(hToken);
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Now check the SID Length */
    UserSid = TokenInfo->User.Sid;
    Length = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);

    /* Allocate a buffer for the Security Descriptor, with SID and DACL */
    ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
    if (!ProcSd)
    {
        Status = STATUS_NO_MEMORY;
        goto Quickie;
    }

    /* Set the pointer to the DACL */
    Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH);

    /* Now create the SD itself */
    Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSS: SD creation failed - status = %lx\n", Status);
        goto Quickie;
    }

    /* Create the DACL for it*/
    Status = RtlCreateAcl(Dacl, Length, ACL_REVISION2);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSS: DACL creation failed - status = %lx\n", Status);
        goto Quickie;
    }

    /* Create the ACE */
    Status = RtlAddAccessAllowedAce(Dacl,
                                    ACL_REVISION,
                                    PROCESS_VM_READ | PROCESS_VM_WRITE |
                                    PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
                                    PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME |
                                    PROCESS_QUERY_INFORMATION | READ_CONTROL,
                                    UserSid);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSS: ACE creation failed - status = %lx\n", Status);
        goto Quickie;
    }

    /* Clear the DACL in the SD */
    Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSS: set DACL failed - status = %lx\n", Status);
        goto Quickie;
    }

    /* Write the SD into the Process */
    Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSS: set process DACL failed - status = %lx\n", Status);
        goto Quickie;
    }

    /* Free the memory and return */
Quickie:
    if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd);
    RtlFreeHeap(CsrHeap, 0, TokenInfo);
    return Status;
}
Example #10
0
static
HANDLE
K32CreateDBMonMutex(void)
{
    static SID_IDENTIFIER_AUTHORITY siaNTAuth = {SECURITY_NT_AUTHORITY};
    static SID_IDENTIFIER_AUTHORITY siaWorldAuth = {SECURITY_WORLD_SID_AUTHORITY};
    HANDLE hMutex;

    /* SIDs to be used in the DACL */
    PSID psidSystem = NULL;
    PSID psidAdministrators = NULL;
    PSID psidEveryone = NULL;

    /* buffer for the DACL */
    PVOID pDaclBuf = NULL;

    /* minimum size of the DACL: an ACL descriptor and three ACCESS_ALLOWED_ACE
       headers. We'll add the size of SIDs when we'll know it
    */
    SIZE_T nDaclBufSize =
         sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE) -
                        sizeof(((ACCESS_ALLOWED_ACE*)0)->SidStart)) * 3;

    /* security descriptor of the mutex */
    SECURITY_DESCRIPTOR sdMutexSecurity;

    /* attributes of the mutex object we'll create */
    SECURITY_ATTRIBUTES saMutexAttribs = {sizeof(saMutexAttribs),
                                          &sdMutexSecurity,
                                          TRUE};

    NTSTATUS nErrCode;

    /* first, try to open the mutex */
    hMutex = OpenMutexW (SYNCHRONIZE | READ_CONTROL | MUTANT_QUERY_STATE,
                         TRUE,
                         L"DBWinMutex");

    if(hMutex != NULL)
    {
        /* success */
        return hMutex;
    }
    /* error other than the mutex not being found */
    else if(GetLastError() != ERROR_FILE_NOT_FOUND)
    {
        /* failure */
        return NULL;
    }

	/* if the mutex doesn't exist, create it */

    /* first, set up the mutex security */
    /* allocate the NT AUTHORITY\SYSTEM SID */
    nErrCode = RtlAllocateAndInitializeSid(&siaNTAuth,
                                           1,
                                           SECURITY_LOCAL_SYSTEM_RID,
                                           0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           &psidSystem);

    /* failure */
    if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;

    /* allocate the BUILTIN\Administrators SID */
    nErrCode = RtlAllocateAndInitializeSid(&siaNTAuth,
                                           2,
                                           SECURITY_BUILTIN_DOMAIN_RID,
                                           DOMAIN_ALIAS_RID_ADMINS,
                                           0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           &psidAdministrators);

    /* failure */
    if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;

    /* allocate the Everyone SID */
    nErrCode = RtlAllocateAndInitializeSid(&siaWorldAuth,
                                           1,
                                           0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           &psidEveryone);

    /* failure */
    if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;

    /* allocate space for the SIDs too */
    nDaclBufSize += RtlLengthSid(psidSystem);
    nDaclBufSize += RtlLengthSid(psidAdministrators);
    nDaclBufSize += RtlLengthSid(psidEveryone);

    /* allocate the buffer for the DACL */
    pDaclBuf = GlobalAlloc(GMEM_FIXED, nDaclBufSize);

    /* failure */
    if(pDaclBuf == NULL) goto l_Cleanup;

    /* create the DACL */
    nErrCode = RtlCreateAcl(pDaclBuf, nDaclBufSize, ACL_REVISION);

    /* failure */
    if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;

    /* grant the minimum required access to Everyone */
    nErrCode = RtlAddAccessAllowedAce(pDaclBuf,
                                      ACL_REVISION,
                                      SYNCHRONIZE |
                                      READ_CONTROL |
                                      MUTANT_QUERY_STATE,
                                      psidEveryone);

    /* failure */
    if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;

    /* grant full access to BUILTIN\Administrators */
    nErrCode = RtlAddAccessAllowedAce(pDaclBuf,
                                      ACL_REVISION,
                                      MUTANT_ALL_ACCESS,
                                      psidAdministrators);

    /* failure */
    if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;

    /* grant full access to NT AUTHORITY\SYSTEM */
    nErrCode = RtlAddAccessAllowedAce(pDaclBuf,
                                      ACL_REVISION,
                                      MUTANT_ALL_ACCESS,
                                      psidSystem);

    /* failure */
    if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;

    /* create the security descriptor */
    nErrCode = RtlCreateSecurityDescriptor(&sdMutexSecurity,
                                           SECURITY_DESCRIPTOR_REVISION);

    /* failure */
    if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;

    /* set the descriptor's DACL to the ACL we created */
    nErrCode = RtlSetDaclSecurityDescriptor(&sdMutexSecurity,
                                            TRUE,
                                            pDaclBuf,
                                            FALSE);

    /* failure */
    if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;

    /* create the mutex */
    hMutex = CreateMutexW(&saMutexAttribs, FALSE, L"DBWinMutex");

l_Cleanup:
    /* free the buffers */
    if(pDaclBuf) GlobalFree(pDaclBuf);
    if(psidEveryone) RtlFreeSid(psidEveryone);
    if(psidAdministrators) RtlFreeSid(psidAdministrators);
    if(psidSystem) RtlFreeSid(psidSystem);

	return hMutex;
}
Example #11
0
/*
 * @implemented
 */
BOOL WINAPI
CheckTokenMembership(IN HANDLE ExistingTokenHandle,
                     IN PSID SidToCheck,
                     OUT PBOOL IsMember)
{
    PISECURITY_DESCRIPTOR SecurityDescriptor = NULL;
    ACCESS_MASK GrantedAccess;
    struct
    {
        PRIVILEGE_SET PrivilegeSet;
        LUID_AND_ATTRIBUTES Privileges[4];
    } PrivBuffer;
    ULONG PrivBufferSize = sizeof(PrivBuffer);
    GENERIC_MAPPING GenericMapping =
    {
        STANDARD_RIGHTS_READ,
        STANDARD_RIGHTS_WRITE,
        STANDARD_RIGHTS_EXECUTE,
        STANDARD_RIGHTS_ALL
    };
    PACL Dacl;
    ULONG SidLen;
    HANDLE hToken = NULL;
    NTSTATUS Status, AccessStatus;

    /* doesn't return gracefully if IsMember is NULL! */
    *IsMember = FALSE;

    SidLen = RtlLengthSid(SidToCheck);

    if (ExistingTokenHandle == NULL)
    {
        Status = NtOpenThreadToken(NtCurrentThread(),
                                   TOKEN_QUERY,
                                   FALSE,
                                   &hToken);

        if (Status == STATUS_NO_TOKEN)
        {
            /* we're not impersonating, open the primary token */
            Status = NtOpenProcessToken(NtCurrentProcess(),
                                        TOKEN_QUERY | TOKEN_DUPLICATE,
                                        &hToken);
            if (NT_SUCCESS(Status))
            {
                HANDLE hNewToken = FALSE;
                BOOL DupRet;

                /* duplicate the primary token to create an impersonation token */
                DupRet = DuplicateTokenEx(hToken,
                                          TOKEN_QUERY | TOKEN_IMPERSONATE,
                                          NULL,
                                          SecurityImpersonation,
                                          TokenImpersonation,
                                          &hNewToken);

                NtClose(hToken);

                if (!DupRet)
                {
                    WARN("Failed to duplicate the primary token!\n");
                    return FALSE;
                }

                hToken = hNewToken;
            }
        }

        if (!NT_SUCCESS(Status))
        {
            goto Cleanup;
        }
    }
    else
    {
        hToken = ExistingTokenHandle;
    }

    /* create a security descriptor */
    SecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(),
                                         0,
                                         sizeof(SECURITY_DESCRIPTOR) +
                                             sizeof(ACL) + SidLen +
                                             sizeof(ACCESS_ALLOWED_ACE));
    if (SecurityDescriptor == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Cleanup;
    }

    Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* set the owner and group */
    Status = RtlSetOwnerSecurityDescriptor(SecurityDescriptor,
                                           SidToCheck,
                                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlSetGroupSecurityDescriptor(SecurityDescriptor,
                                           SidToCheck,
                                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* create the DACL */
    Dacl = (PACL)(SecurityDescriptor + 1);
    Status = RtlCreateAcl(Dacl,
                          sizeof(ACL) + SidLen + sizeof(ACCESS_ALLOWED_ACE),
                          ACL_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlAddAccessAllowedAce(Dacl,
                                    ACL_REVISION,
                                    0x1,
                                    SidToCheck);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* assign the DACL to the security descriptor */
    Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
                                          TRUE,
                                          Dacl,
                                          FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* it's time to perform the access check. Just use _some_ desired access right
       (same as for the ACE) and see if we're getting it granted. This indicates
       our SID is a member of the token. We however can't use a generic access
       right as those aren't mapped and return an error (STATUS_GENERIC_NOT_MAPPED). */
    Status = NtAccessCheck(SecurityDescriptor,
                           hToken,
                           0x1,
                           &GenericMapping,
                           &PrivBuffer.PrivilegeSet,
                           &PrivBufferSize,
                           &GrantedAccess,
                           &AccessStatus);
    if (NT_SUCCESS(Status) && NT_SUCCESS(AccessStatus) && (GrantedAccess == 0x1))
    {
        *IsMember = TRUE;
    }

Cleanup:
    if (hToken != NULL && hToken != ExistingTokenHandle)
    {
        NtClose(hToken);
    }

    if (SecurityDescriptor != NULL)
    {
        RtlFreeHeap(RtlGetProcessHeap(),
                    0,
                    SecurityDescriptor);
    }

    if (!NT_SUCCESS(Status))
    {
        SetLastError(RtlNtStatusToDosError(Status));
        return FALSE;
    }

    return TRUE;
}
Example #12
0
/******************************************************************************
 * InitializeSecurityDescriptor [ADVAPI32.@]
 *
 * PARAMS
 *   pDescr   []
 *   revision []
 */
BOOL WINAPI
InitializeSecurityDescriptor( SECURITY_DESCRIPTOR *pDescr, DWORD revision )
{
    CallWin32ToNt (RtlCreateSecurityDescriptor(pDescr, revision ));
}
Example #13
0
NTSTATUS
NtOpenThreadToken(
    IN HANDLE ThreadHandle,
    IN ACCESS_MASK DesiredAccess,
    IN BOOLEAN OpenAsSelf,
    OUT PHANDLE TokenHandle
    )

/*++


Routine Description:

Open a token object associated with a thread and return a handle that
may be used to access that token.

Arguments:

    ThreadHandle - Specifies the thread whose token is to be opened.

    DesiredAccess - Is an access mask indicating which access types
        are desired to the token.  These access types are reconciled
        with the Discretionary Access Control list of the token to
        determine whether the accesses will be granted or denied.

    OpenAsSelf - Is a boolean value indicating whether the access should
        be made using the calling thread's current security context, which
        may be that of a client if impersonating, or using the caller's
        process-level security context.  A value of FALSE indicates the
        caller's current context should be used un-modified.  A value of
        TRUE indicates the request should be fulfilled using the process
        level security context.

        This parameter is necessary to allow a server process to open
        a client's token when the client specified IDENTIFICATION level
        impersonation.  In this case, the caller would not be able to
        open the client's token using the client's context (because you
        can't create executive level objects using IDENTIFICATION level
        impersonation).

    TokenHandle - Receives the handle of the newly opened token.

Return Value:

    STATUS_SUCCESS - Indicates the operation was successful.

    STATUS_NO_TOKEN - Indicates an attempt has been made to open a
        token associated with a thread that is not currently
        impersonating a client.

    STATUS_CANT_OPEN_ANONYMOUS - Indicates the client requested anonymous
        impersonation level.  An anonymous token can not be openned.

--*/
{

    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status;

    PVOID Token;
    PTOKEN NewToken = NULL;
    BOOLEAN CopyOnOpen;
    BOOLEAN EffectiveOnly;
    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
    SE_IMPERSONATION_STATE DisabledImpersonationState;
    BOOLEAN RestoreImpersonationState = FALSE;

    HANDLE LocalHandle;
    SECURITY_DESCRIPTOR SecurityDescriptor;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PACL NewAcl = NULL;
    PETHREAD Thread;
    PETHREAD OriginalThread = NULL;
    PACCESS_TOKEN PrimaryToken;
    SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;

    PAGED_CODE();

    PreviousMode = KeGetPreviousMode();

    //
    //  Probe parameters
    //

    if (PreviousMode != KernelMode) {

        try {

            ProbeForWriteHandle(TokenHandle);

        } except(EXCEPTION_EXECUTE_HANDLER) {
            return GetExceptionCode();
        }  // end_try

    } //end_if

    //
    // Valdiate access to the thread and obtain a pointer to the
    // thread's token (if there is one).  If successful, this will
    // cause the token's reference count to be incremented.
    //
    // This routine disabled impersonation as necessary to properly
    // honor the OpenAsSelf flag.
    //

    Status = SepOpenTokenOfThread( ThreadHandle,
                                  OpenAsSelf,
                                  ((PACCESS_TOKEN *)&Token),
                                  &OriginalThread,
                                  &CopyOnOpen,
                                  &EffectiveOnly,
                                  &ImpersonationLevel
                                  );

    if (!NT_SUCCESS(Status)) {
        return Status;
    }


    //
    //  The token was successfully referenced.
    //

    //
    // We need to create and/or open a token object, so disable impersonation
    // if necessary.
    //

    if (OpenAsSelf) {
         RestoreImpersonationState = PsDisableImpersonation(
                                         PsGetCurrentThread(),
                                         &DisabledImpersonationState
                                         );
    }

    //
    //  If the CopyOnOpen flag is not set, then the token can be
    //  opened directly.  Otherwise, the token must be duplicated,
    //  and a handle to the duplicate returned.
    //

    if (CopyOnOpen) {

        //
        // Create the new security descriptor for the token.
        //
        // We must obtain the correct SID to put into the Dacl.  Do this
        // by finding the process associated with the passed thread
        // and grabbing the User SID out of that process's token.
        // If we just use the current SubjectContext, we'll get the
        // SID of whoever is calling us, which isn't what we want.
        //

        Status = ObReferenceObjectByHandle(
                     ThreadHandle,
                     THREAD_ALL_ACCESS,
                     PsThreadType,
                     KernelMode,
                     (PVOID)&Thread,
                     NULL
                     );

        //
        // Verify that the handle is still pointer to the same thread\
        // BUGBUG: wrong error code.
        //

        if (NT_SUCCESS(Status) && (Thread != OriginalThread)) {
            Status = STATUS_OBJECT_TYPE_MISMATCH;
        }

        if (NT_SUCCESS(Status)) {

            PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);

            Status = SepCreateImpersonationTokenDacl(
                         (PTOKEN)Token,
                         PrimaryToken,
                         &NewAcl
                         );

            PsDereferencePrimaryToken( PrimaryToken );

            if (NT_SUCCESS( Status )) {

                if (NewAcl != NULL) {

                    //
                    // There exist tokens that either do not have security descriptors at all,
                    // or have security descriptors, but do not have DACLs.  In either case, do
                    // nothing.
                    //

                    Status = RtlCreateSecurityDescriptor ( &SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
                    ASSERT( NT_SUCCESS( Status ));

                    Status = RtlSetDaclSecurityDescriptor (
                                 &SecurityDescriptor,
                                 TRUE,
                                 NewAcl,
                                 FALSE
                                 );

                    ASSERT( NT_SUCCESS( Status ));
                }

                InitializeObjectAttributes(
                    &ObjectAttributes,
                    NULL,
                    0L,
                    NULL,
                    NewAcl == NULL ? NULL : &SecurityDescriptor
                    );

                //
                // Open a copy of the token
                //

                Status = SepDuplicateToken(
                             (PTOKEN)Token,        // ExistingToken
                             &ObjectAttributes,    // ObjectAttributes
                             EffectiveOnly,        // EffectiveOnly
                             TokenImpersonation,   // TokenType
                             ImpersonationLevel,   // ImpersonationLevel
                             KernelMode,           // RequestorMode must be kernel mode
                             &NewToken
                             );

                if (NT_SUCCESS( Status )) {

                    //
                    // Reference the token so it doesn't go away
                    //

                    ObReferenceObject(NewToken);

                    //
                    //  Insert the new token
                    //

                    Status = ObInsertObject( NewToken,
                                             NULL,
                                             DesiredAccess,
                                             0,
                                             (PVOID *)NULL,
                                             &LocalHandle
                                             );
                }
            }
        }


    } else {

        //
        // We do not have to modify the security on the token in the static case,
        // because in all the places in the system where impersonation takes place
        // over a secure transport (e.g., LPC), CopyOnOpen is set.  The only reason
        // we'be be here is if the impersonation is taking place because someone did
        // an NtSetInformationThread and passed in a token.
        //
        // In that case, we absolutely do not want to give the caller guaranteed
        // access, because that would allow anyone who has access to a thread to
        // impersonate any of that thread's clients for any access.
        //

        //
        //  Open the existing token
        //

        Status = ObOpenObjectByPointer(
                     (PVOID)Token,         // Object
                     0,                    // HandleAttributes
                     NULL,                 // AccessState
                     DesiredAccess,        // DesiredAccess
                     SepTokenObjectType,   // ObjectType
                     PreviousMode,         // AccessMode
                     &LocalHandle          // Handle
                     );
    }

    if (NewAcl != NULL) {
        ExFreePool( NewAcl );
    }

    if (RestoreImpersonationState) {
        PsRestoreImpersonation(
            PsGetCurrentThread(),
            &DisabledImpersonationState
            );
    }

    //
    //  And decrement the reference count of the existing token to counter
    //  the action performed by PsOpenTokenOfThread.  If the open
    //  was successful, the handle will have caused the token's
    //  reference count to have been incremented.
    //

    ObDereferenceObject( Token );

    if (NT_SUCCESS( Status ) && CopyOnOpen) {

        //
        // Assign the newly duplicated token to the thread.
        //

        PsImpersonateClient( Thread,
                             NewToken,
                             FALSE,  // turn off CopyOnOpen flag
                             EffectiveOnly,
                             ImpersonationLevel
                             );

    }

    //
    // We've impersonated the token so let go of oure reference
    //

    if (NewToken != NULL) {
        ObDereferenceObject( NewToken );
    }

    if (CopyOnOpen && (Thread != NULL)) {

        ObDereferenceObject( Thread );
    }

    if (OriginalThread != NULL) {
        ObDereferenceObject(OriginalThread);
    }

    //
    //  Return the new handle
    //

    if (NT_SUCCESS(Status)) {
        try { *TokenHandle = LocalHandle; }
            except(EXCEPTION_EXECUTE_HANDLER) { return GetExceptionCode(); }
    }

    return Status;

}
Example #14
0
NTSTATUS
SspCreateTokenDacl(
    HANDLE Token
    )
/*++

RoutineDescription:

    Creates a new DACL for the token granting the server and client
    all access to the token.

Arguments:

    Token - Handle to an impersonation token open for TOKEN_QUERY and
        WRITE_DAC

Return Value:

    STATUS_INSUFFICIENT_RESOURCES - insufficient memory to complete
        the function.

    Errors from NtSetSecurityObject

--*/
{
    NTSTATUS Status;
    PTOKEN_USER ProcessTokenUser = NULL;
    PTOKEN_USER ThreadTokenUser = NULL;
    HANDLE ProcessToken = NULL;
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    ULONG AclLength;
    PACL NewDacl = NULL;
    SECURITY_DESCRIPTOR SecurityDescriptor;

    //
    // Build the two well known sids we need.
    //

    EnterCriticalSection(&csCheaterList);

    if (SspGlobalLocalSystemSid == NULL)
    {
        Status = RtlAllocateAndInitializeSid(
                    &NtAuthority,
                    1,
                    SECURITY_LOCAL_SYSTEM_RID,
                    0,0,0,0,0,0,0,
                    &SspGlobalLocalSystemSid
                    );
        if (!NT_SUCCESS(Status))
        {
            LeaveCriticalSection(&csCheaterList);
            goto Cleanup;
        }
    }

    if (SspGlobalAliasAdminsSid == NULL)
    {

        Status = RtlAllocateAndInitializeSid(
                    &NtAuthority,
                    2,
                    SECURITY_BUILTIN_DOMAIN_RID,
                    DOMAIN_ALIAS_RID_ADMINS,
                    0,0,0,0,0,0,
                    &SspGlobalAliasAdminsSid
                    );
        if (!NT_SUCCESS(Status))
        {
            LeaveCriticalSection(&csCheaterList);
            goto Cleanup;
        }

    }

    LeaveCriticalSection(&csCheaterList);

    //
    // Open the process token to find out the user sid
    //

    Status = NtOpenProcessToken(
                NtCurrentProcess(),
                TOKEN_QUERY,
                &ProcessToken
                );
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = SspGetTokenUser(
                ProcessToken,
                &ProcessTokenUser
                );

    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    //
    // Now get the token user for the thread.
    //
    Status = SspGetTokenUser(
                Token,
                &ThreadTokenUser
                );

    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    AclLength = 4 * sizeof( ACCESS_ALLOWED_ACE ) - 4 * sizeof( ULONG ) +
                RtlLengthSid( ProcessTokenUser->User.Sid ) +
                RtlLengthSid( ThreadTokenUser->User.Sid ) +
                RtlLengthSid( SspGlobalLocalSystemSid ) +
                RtlLengthSid( SspGlobalAliasAdminsSid ) +
                sizeof( ACL );

    NewDacl = LocalAlloc(0, AclLength );

    if (NewDacl == NULL) {

        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Cleanup;
    }

    Status = RtlCreateAcl( NewDacl, AclLength, ACL_REVISION2 );
    ASSERT(NT_SUCCESS( Status ));

    Status = RtlAddAccessAllowedAce (
                 NewDacl,
                 ACL_REVISION2,
                 TOKEN_ALL_ACCESS,
                 ProcessTokenUser->User.Sid
                 );
    ASSERT( NT_SUCCESS( Status ));

    Status = RtlAddAccessAllowedAce (
                 NewDacl,
                 ACL_REVISION2,
                 TOKEN_ALL_ACCESS,
                 ThreadTokenUser->User.Sid
                 );
    ASSERT( NT_SUCCESS( Status ));

    Status = RtlAddAccessAllowedAce (
                 NewDacl,
                 ACL_REVISION2,
                 TOKEN_ALL_ACCESS,
                 SspGlobalAliasAdminsSid
                 );
    ASSERT( NT_SUCCESS( Status ));

    Status = RtlAddAccessAllowedAce (
                 NewDacl,
                 ACL_REVISION2,
                 TOKEN_ALL_ACCESS,
                 SspGlobalLocalSystemSid
                 );
    ASSERT( NT_SUCCESS( Status ));

    Status = RtlCreateSecurityDescriptor (
                 &SecurityDescriptor,
                 SECURITY_DESCRIPTOR_REVISION
                 );
    ASSERT( NT_SUCCESS( Status ));

    Status = RtlSetDaclSecurityDescriptor(
                 &SecurityDescriptor,
                 TRUE,
                 NewDacl,
                 FALSE
                 );

    ASSERT( NT_SUCCESS( Status ));

    Status = NtSetSecurityObject(
                 Token,
                 DACL_SECURITY_INFORMATION,
                 &SecurityDescriptor
                 );

    ASSERT( NT_SUCCESS( Status ));


Cleanup:

    if (ThreadTokenUser != NULL) {
        LocalFree( ThreadTokenUser );
    }

    if (ProcessTokenUser != NULL) {
        LocalFree( ProcessTokenUser );
    }

    if (NewDacl != NULL) {
        LocalFree( NewDacl );
    }

    if (ProcessToken != NULL)
    {
        NtClose(ProcessToken);
    }

    return( Status );
}
Example #15
0
int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
    DLGPROC	       	   lpDiagProc;
    NTSTATUS           Status;
    STRING	       	   EventName;
    UNICODE_STRING     EventUnicodeName;
    OBJECT_ATTRIBUTES  EventAttributes;


    // Prevent compiler from complaining..
    //
    hPrevInst;
    lpCmdLine;
    nCmdShow;


    // Open the log file for logging possible errors
    //
    pfLog = fopen (LOG_FILE, "w");


    // Create public share security descriptor for all the named objects
    //

    Status = RtlCreateSecurityDescriptor (
		&SecDescriptor,
		SECURITY_DESCRIPTOR_REVISION1
		);
    if (!NT_SUCCESS(Status)) {
	fprintf (pfLog, "WSTDUMP: main () - RtlCreateSecurityDescriptor() "
		       "failed - %lx\n", Status);
	exit (1);
    }

    Status = RtlSetDaclSecurityDescriptor (
		&SecDescriptor,	   	// SecurityDescriptor
		TRUE,		   		// DaclPresent
		NULL,		   		// Dacl
		FALSE		   		// DaclDefaulted
		);
    if (!NT_SUCCESS(Status)) {
	fprintf (pfLog, "WSTDUMP: main () - RtlSetDaclSecurityDescriptor() "
		       "failed - %lx\n", Status);
	exit (1);
    }


    // Initialization for DONE event creation
    //
    RtlInitString (&EventName, DONEEVENTNAME);

    Status = RtlAnsiStringToUnicodeString (&EventUnicodeName,
					   &EventName,
                                           TRUE);
    if (NT_SUCCESS(Status)) {
	InitializeObjectAttributes (&EventAttributes,
				    &EventUnicodeName,
				    OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
				    NULL,
				    &SecDescriptor);
    }
    else {
       fprintf (pfLog, "WSTDUMP: main () - RtlAnsiStringToUnicodeString() "
                       "failed for DUMP event name - %lx\n", Status);
	   exit (1);
    }
    //
    // Create DONE event
    //
    Status = NtCreateEvent (&hDoneEvent,
                            EVENT_QUERY_STATE    |
                              EVENT_MODIFY_STATE |
                              SYNCHRONIZE,
							&EventAttributes,
                            NotificationEvent,
                            TRUE);
    if (!NT_SUCCESS(Status)) {
        fprintf (pfLog, "WSTDUMP: main () - NtCreateEvent() "
                        "failed to create DUMP event - %lx\n", Status);
        exit (1);
    }


    // Initialization for DUMP event creation
    //
    RtlInitString (&EventName, DUMPEVENTNAME);

    Status = RtlAnsiStringToUnicodeString (&EventUnicodeName,
					   &EventName,
                                           TRUE);
    if (NT_SUCCESS(Status)) {
	InitializeObjectAttributes (&EventAttributes,
				    &EventUnicodeName,
				    OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
				    NULL,
				    &SecDescriptor);
    }
    else {
        fprintf (pfLog, "WSTDUMP: main () - RtlAnsiStringToUnicodeString() "
                       "failed for DUMP event name - %lx\n", Status);
        exit (1);
    }
    //
    // Create DUMP event
    //
    Status = NtCreateEvent (&hDumpEvent,
                            EVENT_QUERY_STATE    |
                              EVENT_MODIFY_STATE |
                              SYNCHRONIZE,
							&EventAttributes,
                            NotificationEvent,
                            FALSE);
    if (!NT_SUCCESS(Status)) {
        fprintf (pfLog, "WSTDUMP: main () - NtCreateEvent() "
                        "failed to create DUMP event - %lx\n", Status);
        exit (1);
    }


    // Initialization for CLEAR event creation
    //
    RtlInitString (&EventName, CLEAREVENTNAME);

    Status = RtlAnsiStringToUnicodeString (&EventUnicodeName,
					   &EventName,
                                           TRUE);
    if (NT_SUCCESS(Status)) {
	InitializeObjectAttributes (&EventAttributes,
				    &EventUnicodeName,
				    OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
				    NULL,
				    &SecDescriptor);
    }
    else {
        fprintf (pfLog, "WSTDUMP: main () - RtlAnsiStringToUnicodeString() "
                        "failed for CLEAR event name - %lx\n", Status);
        exit (1);
    }
    //
    // Create CLEAR event
    //
    Status = NtCreateEvent (&hClearEvent,
                            EVENT_QUERY_STATE    |
                              EVENT_MODIFY_STATE |
                              SYNCHRONIZE,
							&EventAttributes,
                            NotificationEvent,
                            FALSE);
    if (!NT_SUCCESS(Status)) {
        fprintf (pfLog, "WSTDUMP: main () - NtCreateEvent() "
                        "failed to create CLEAR event - %lx\n", Status);
        exit (1);
    }


    // Initialization for PAUSE event creation
    //
    RtlInitString (&EventName, PAUSEEVENTNAME);

    Status = RtlAnsiStringToUnicodeString (&EventUnicodeName,
					   &EventName,
                                           TRUE);
    if (NT_SUCCESS(Status)) {
	InitializeObjectAttributes (&EventAttributes,
				    &EventUnicodeName,
				    OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
				    NULL,
				    &SecDescriptor);
    }
    else {
        fprintf (pfLog, "WSTDUMP: main () - RtlAnsiStringToUnicodeString() "
			"failed for PAUSE event name - %lx\n", Status);
        exit (1);
    }
    //
    // Create PAUSE event
    //
    Status = NtCreateEvent (&hPauseEvent,
                            EVENT_QUERY_STATE    |
                              EVENT_MODIFY_STATE |
                              SYNCHRONIZE,
							&EventAttributes,
                            NotificationEvent,
                            FALSE);
    if (!NT_SUCCESS(Status)) {
        fprintf (pfLog, "WSTDUMP: main () - NtCreateEvent() "
			"failed to create PAUSE event - %lx\n", Status);
        exit (1);
    }


    //
    // show dialog box
    //
    lpDiagProc = (DLGPROC)DialogProc;
    DialogBox(hInstance, "DumpDialog", NULL, lpDiagProc);

    return (0);

} /* main */
Example #16
0
VOID
NTAPI
BaseInitializeStaticServerData(IN PCSR_SERVER_DLL LoadedServerDll)
{
    NTSTATUS Status;
    BOOLEAN Success;
    WCHAR Buffer[MAX_PATH];
    PWCHAR HeapBuffer;
    UNICODE_STRING SystemRootString;
    UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%");
    UNICODE_STRING BaseSrvCSDString;
    UNICODE_STRING BaseSrvWindowsDirectory;
    UNICODE_STRING BaseSrvWindowsSystemDirectory;
    UNICODE_STRING BnoString;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG SessionId;
    HANDLE BaseSrvNamedObjectDirectory;
    HANDLE BaseSrvRestrictedObjectDirectory;
    PACL BnoDacl, BnoRestrictedDacl;
    PSECURITY_DESCRIPTOR BnoSd;
    HANDLE SymHandle;
    UNICODE_STRING DirectoryName, SymlinkName;
    ULONG LuidEnabled;
    RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] =
    {
        {
            NULL,
            RTL_QUERY_REGISTRY_DIRECT,
            L"CSDVersion",
            &BaseSrvCSDString,
            REG_NONE, NULL, 0
        },

        {0}
    };

    /* Initialize the memory */
    BaseSrvHeap = RtlGetProcessHeap();                  // Initialize our own heap.
    BaseSrvSharedHeap = LoadedServerDll->SharedSection; // Get the CSR shared heap.

    /* Get the session ID */
    SessionId = NtCurrentPeb()->SessionId;

    /* Get the Windows directory */
    RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer));
    Status = RtlExpandEnvironmentStrings_U(NULL,
                                           &UnexpandedSystemRootString,
                                           &SystemRootString,
                                           NULL);
    ASSERT(NT_SUCCESS(Status));

    /* Create the base directory */
    Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL;
    Success = RtlCreateUnicodeString(&BaseSrvWindowsDirectory,
                                     SystemRootString.Buffer);
    ASSERT(Success);

    /* Create the system directory */
    wcscat(SystemRootString.Buffer, L"\\System32");
    Success = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory,
                                     SystemRootString.Buffer);
    ASSERT(Success);

    /* Create the kernel32 path */
    wcscat(SystemRootString.Buffer, L"\\kernel32.dll");
    Success = RtlCreateUnicodeString(&BaseSrvKernel32DllPath,
                                     SystemRootString.Buffer);
    ASSERT(Success);

    /* FIXME: Check Session ID */
    wcscpy(Buffer, L"\\BaseNamedObjects");
    RtlInitUnicodeString(&BnoString, Buffer);

    /* Allocate the server data */
    BaseStaticServerData = RtlAllocateHeap(BaseSrvSharedHeap,
                                           HEAP_ZERO_MEMORY,
                                           sizeof(BASE_STATIC_SERVER_DATA));
    ASSERT(BaseStaticServerData != NULL);

    /* Process timezone information */
    BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID;
    BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0;
    Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
                                      &BaseStaticServerData->TimeOfDay,
                                      sizeof(BaseStaticServerData->TimeOfDay),
                                      NULL);
    ASSERT(NT_SUCCESS(Status));

    /* Make a shared heap copy of the Windows directory */
    BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory;
    HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
                                 0,
                                 BaseSrvWindowsDirectory.MaximumLength);
    ASSERT(HeapBuffer);
    RtlCopyMemory(HeapBuffer,
                  BaseStaticServerData->WindowsDirectory.Buffer,
                  BaseSrvWindowsDirectory.MaximumLength);
    BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer;

    /* Make a shared heap copy of the System directory */
    BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory;
    HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
                                 0,
                                 BaseSrvWindowsSystemDirectory.MaximumLength);
    ASSERT(HeapBuffer);
    RtlCopyMemory(HeapBuffer,
                  BaseStaticServerData->WindowsSystemDirectory.Buffer,
                  BaseSrvWindowsSystemDirectory.MaximumLength);
    BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer;

    /* This string is not used */
    RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory,
                              NULL,
                              0);

    /* Make a shared heap copy of the BNO directory */
    BaseStaticServerData->NamedObjectDirectory = BnoString;
    BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length +
                                                               sizeof(UNICODE_NULL);
    HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
                                 0,
                                 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
    ASSERT(HeapBuffer);
    RtlCopyMemory(HeapBuffer,
                  BaseStaticServerData->NamedObjectDirectory.Buffer,
                  BaseStaticServerData->NamedObjectDirectory.MaximumLength);
    BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer;

    /*
     * Confirmed that in Windows, CSDNumber and RCNumber are actually Length
     * and MaximumLength of the CSD String, since the same UNICODE_STRING is
     * being queried twice, the first time as a ULONG!
     *
     * Somehow, in Windows this doesn't cause a buffer overflow, but it might
     * in ReactOS, so this code is disabled until someone figures out WTF.
     */
    BaseStaticServerData->CSDNumber = 0;
    BaseStaticServerData->RCNumber = 0;

    /* Initialize the CSD string and query its value from the registry */
    RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer));
    Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
                                    L"",
                                    BaseServerRegistryConfigurationTable,
                                    NULL,
                                    NULL);
    if (NT_SUCCESS(Status))
    {
        /* Copy into the shared buffer */
        wcsncpy(BaseStaticServerData->CSDVersion,
                BaseSrvCSDString.Buffer,
                BaseSrvCSDString.Length / sizeof(WCHAR));
    }
    else
    {
        /* NULL-terminate to indicate nothing is there */
        BaseStaticServerData->CSDVersion[0] = UNICODE_NULL;
    }

    /* Cache the system information */
    Status = NtQuerySystemInformation(SystemBasicInformation,
                                      &BaseStaticServerData->SysInfo,
                                      sizeof(BaseStaticServerData->SysInfo),
                                      NULL);
    ASSERT(NT_SUCCESS(Status));

    /* Setup the ini file mappings */
    Status = BaseSrvInitializeIniFileMappings(BaseStaticServerData);
    ASSERT(NT_SUCCESS(Status));

    /* FIXME: Should query the registry for these */
    BaseStaticServerData->DefaultSeparateVDM = FALSE;
    BaseStaticServerData->IsWowTaskReady = FALSE;

    /* Allocate a security descriptor and create it */
    BnoSd = RtlAllocateHeap(BaseSrvHeap, 0, 1024);
    ASSERT(BnoSd);
    Status = RtlCreateSecurityDescriptor(BnoSd, SECURITY_DESCRIPTOR_REVISION);
    ASSERT(NT_SUCCESS(Status));

    /* Create the BNO and \Restricted DACLs */
    Status = CreateBaseAcls(&BnoDacl, &BnoRestrictedDacl);
    ASSERT(NT_SUCCESS(Status));

    /* Set the BNO DACL as active for now */
    Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoDacl, FALSE);
    ASSERT(NT_SUCCESS(Status));

    /* Create the BNO directory */
    RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
    InitializeObjectAttributes(&ObjectAttributes,
                               &BnoString,
                               OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
                               NULL,
                               BnoSd);
    Status = NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory,
                                     DIRECTORY_ALL_ACCESS,
                                     &ObjectAttributes);
    ASSERT(NT_SUCCESS(Status));

    /* Check if we are session 0 */
    if (SessionId == 0)
    {
        /* Mark this as a session 0 directory */
        Status = NtSetInformationObject(BaseSrvNamedObjectDirectory,
                                        ObjectSessionInformation,
                                        NULL,
                                        0);
        ASSERT(NT_SUCCESS(Status));
    }

    /* Check if LUID device maps are enabled */
    Status = NtQueryInformationProcess(NtCurrentProcess(),
                                       ProcessLUIDDeviceMapsEnabled,
                                       &LuidEnabled,
                                       sizeof(LuidEnabled),
                                       NULL);
    ASSERT(NT_SUCCESS(Status));
    BaseStaticServerData->LUIDDeviceMapsEnabled = (BOOLEAN)LuidEnabled;
    if (!BaseStaticServerData->LUIDDeviceMapsEnabled)
    {
        /* Make Global point back to BNO */
        RtlInitUnicodeString(&DirectoryName, L"Global");
        RtlInitUnicodeString(&SymlinkName, L"\\BaseNamedObjects");
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DirectoryName,
                                   OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
                                   BaseSrvNamedObjectDirectory,
                                   BnoSd);
        Status = NtCreateSymbolicLinkObject(&SymHandle,
                                            SYMBOLIC_LINK_ALL_ACCESS,
                                            &ObjectAttributes,
                                            &SymlinkName);
        if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);

        /* Make local point back to \Sessions\x\BNO */
        RtlInitUnicodeString(&DirectoryName, L"Local");
        ASSERT(SessionId == 0);
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DirectoryName,
                                   OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
                                   BaseSrvNamedObjectDirectory,
                                   BnoSd);
        Status = NtCreateSymbolicLinkObject(&SymHandle,
                                            SYMBOLIC_LINK_ALL_ACCESS,
                                            &ObjectAttributes,
                                            &SymlinkName);
        if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);

        /* Make Session point back to BNOLINKS */
        RtlInitUnicodeString(&DirectoryName, L"Session");
        RtlInitUnicodeString(&SymlinkName, L"\\Sessions\\BNOLINKS");
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DirectoryName,
                                   OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
                                   BaseSrvNamedObjectDirectory,
                                   BnoSd);
        Status = NtCreateSymbolicLinkObject(&SymHandle,
                                            SYMBOLIC_LINK_ALL_ACCESS,
                                            &ObjectAttributes,
                                            &SymlinkName);
        if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);

        /* Create the BNO\Restricted directory and set the restricted DACL */
        RtlInitUnicodeString(&DirectoryName, L"Restricted");
        Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoRestrictedDacl, FALSE);
        ASSERT(NT_SUCCESS(Status));
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DirectoryName,
                                   OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
                                   BaseSrvNamedObjectDirectory,
                                   BnoSd);
        Status = NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory,
                                         DIRECTORY_ALL_ACCESS,
                                         &ObjectAttributes);
        ASSERT(NT_SUCCESS(Status));
    }

    /* Initialize NLS */
    BaseSrvNLSInit(BaseStaticServerData);

    /* Finally, set the pointer */
    LoadedServerDll->SharedSection = BaseStaticServerData;
}
Example #17
0
NTSTATUS
LsapCreateSecretSd(PSECURITY_DESCRIPTOR *SecretSd,
                   PULONG SecretSdSize)
{
    SECURITY_DESCRIPTOR AbsoluteSd;
    PSECURITY_DESCRIPTOR RelativeSd = NULL;
    ULONG RelativeSdSize = 0;
    PSID AdministratorsSid = NULL;
    PSID EveryoneSid = NULL;
    PSID LocalSystemSid = NULL;
    PACL Dacl = NULL;
    ULONG DaclSize;
    NTSTATUS Status;

    if (SecretSd == NULL || SecretSdSize == NULL)
        return STATUS_INVALID_PARAMETER;

    *SecretSd = NULL;
    *SecretSdSize = 0;

    /* Initialize the SD */
    Status = RtlCreateSecurityDescriptor(&AbsoluteSd,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status))
        return Status;

    Status = RtlAllocateAndInitializeSid(&NtAuthority,
                                         2,
                                         SECURITY_BUILTIN_DOMAIN_RID,
                                         DOMAIN_ALIAS_RID_ADMINS,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         &AdministratorsSid);
    if (!NT_SUCCESS(Status))
        goto done;

    Status = RtlAllocateAndInitializeSid(&WorldSidAuthority,
                                         1,
                                         SECURITY_WORLD_RID,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         &EveryoneSid);
    if (!NT_SUCCESS(Status))
        goto done;

    Status = RtlAllocateAndInitializeSid(&NtAuthority,
                                         1,
                                         SECURITY_LOCAL_SYSTEM_RID,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         &LocalSystemSid);
    if (!NT_SUCCESS(Status))
        goto done;

    /* Allocate and initialize the DACL */
    DaclSize = sizeof(ACL) +
               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AdministratorsSid) +
               sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(EveryoneSid);

    Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
                           HEAP_ZERO_MEMORY,
                           DaclSize);
    if (Dacl == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto done;
    }

    Status = RtlCreateAcl(Dacl,
                          DaclSize,
                          ACL_REVISION);
    if (!NT_SUCCESS(Status))
        goto done;

    Status = RtlAddAccessAllowedAce(Dacl,
                                    ACL_REVISION,
                                    SECRET_ALL_ACCESS,
                                    AdministratorsSid);
    if (!NT_SUCCESS(Status))
        goto done;

    Status = RtlAddAccessAllowedAce(Dacl,
                                    ACL_REVISION,
                                    SECRET_EXECUTE,
                                    EveryoneSid);
    if (!NT_SUCCESS(Status))
        goto done;

    Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd,
                                          TRUE,
                                          Dacl,
                                          FALSE);
    if (!NT_SUCCESS(Status))
        goto done;

    Status = RtlSetGroupSecurityDescriptor(&AbsoluteSd,
                                           LocalSystemSid,
                                           FALSE);
    if (!NT_SUCCESS(Status))
        goto done;

    Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd,
                                           AdministratorsSid,
                                           FALSE);
    if (!NT_SUCCESS(Status))
        goto done;

    Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
                                         RelativeSd,
                                         &RelativeSdSize);
    if (Status != STATUS_BUFFER_TOO_SMALL)
        goto done;

    RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(),
                                 HEAP_ZERO_MEMORY,
                                 RelativeSdSize);
    if (RelativeSd == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto done;
    }

    Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
                                         RelativeSd,
                                         &RelativeSdSize);
    if (!NT_SUCCESS(Status))
        goto done;

    *SecretSd = RelativeSd;
    *SecretSdSize = RelativeSdSize;

done:
    if (Dacl != NULL)
        RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);

    if (AdministratorsSid != NULL)
        RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid);

    if (EveryoneSid != NULL)
        RtlFreeHeap(RtlGetProcessHeap(), 0, EveryoneSid);

    if (LocalSystemSid != NULL)
        RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid);

    if (!NT_SUCCESS(Status))
    {
        if (RelativeSd != NULL)
            RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd);
    }

    return Status;
}
Example #18
0
/**
 * Sets the access control lists of the current window station
 * and desktop to allow all access.
 */
VOID PhSetDesktopWinStaAccess(
    VOID
    )
{
    static SID_IDENTIFIER_AUTHORITY appPackageAuthority = SECURITY_APP_PACKAGE_AUTHORITY;

    HWINSTA wsHandle;
    HDESK desktopHandle;
    ULONG allocationLength;
    PSECURITY_DESCRIPTOR securityDescriptor;
    PACL dacl;
    CHAR allAppPackagesSidBuffer[FIELD_OFFSET(SID, SubAuthority) + sizeof(ULONG) * 2];
    PSID allAppPackagesSid;

    // TODO: Set security on the correct window station and desktop.

    allAppPackagesSid = (PISID)allAppPackagesSidBuffer;
    RtlInitializeSid(allAppPackagesSid, &appPackageAuthority, SECURITY_BUILTIN_APP_PACKAGE_RID_COUNT);
    *RtlSubAuthoritySid(allAppPackagesSid, 0) = SECURITY_APP_PACKAGE_BASE_RID;
    *RtlSubAuthoritySid(allAppPackagesSid, 1) = SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE;

    // We create a DACL that allows everyone to access everything.

    allocationLength = SECURITY_DESCRIPTOR_MIN_LENGTH +
        (ULONG)sizeof(ACL) +
        (ULONG)sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(&PhSeEveryoneSid) +
        (ULONG)sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(allAppPackagesSid);
    securityDescriptor = PhAllocate(allocationLength);
    dacl = (PACL)((PCHAR)securityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);

    RtlCreateSecurityDescriptor(securityDescriptor, SECURITY_DESCRIPTOR_REVISION);

    RtlCreateAcl(dacl, allocationLength - SECURITY_DESCRIPTOR_MIN_LENGTH, ACL_REVISION);
    RtlAddAccessAllowedAce(dacl, ACL_REVISION, GENERIC_ALL, &PhSeEveryoneSid);

    if (WindowsVersion >= WINDOWS_8)
    {
        RtlAddAccessAllowedAce(dacl, ACL_REVISION, GENERIC_ALL, allAppPackagesSid);
    }

    RtlSetDaclSecurityDescriptor(securityDescriptor, TRUE, dacl, FALSE);

    if (wsHandle = OpenWindowStation(
        L"WinSta0",
        FALSE,
        WRITE_DAC
        ))
    {
        PhSetObjectSecurity(wsHandle, DACL_SECURITY_INFORMATION, securityDescriptor);
        CloseWindowStation(wsHandle);
    }

    if (desktopHandle = OpenDesktop(
        L"Default",
        0,
        FALSE,
        WRITE_DAC | DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS
        ))
    {
        PhSetObjectSecurity(desktopHandle, DACL_SECURITY_INFORMATION, securityDescriptor);
        CloseDesktop(desktopHandle);
    }

    PhFree(securityDescriptor);
}
Example #19
0
static NTSTATUS
RtlpSysVolCreateSecurityDescriptor(OUT PISECURITY_DESCRIPTOR *SecurityDescriptor,
                                   OUT PSID *SystemSid)
{
    PSECURITY_DESCRIPTOR AbsSD = NULL;
    PSID LocalSystemSid = NULL;
    PACL Dacl = NULL;
    ULONG DaclSize;
    NTSTATUS Status;

    /* create the local SYSTEM SID */
    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
                                         1,
                                         SECURITY_LOCAL_SYSTEM_RID,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         &LocalSystemSid);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* allocate and initialize the security descriptor */
    AbsSD = RtlpAllocateMemory(sizeof(SECURITY_DESCRIPTOR),
                               'dSeS');
    if (AbsSD == NULL)
    {
        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    Status = RtlCreateSecurityDescriptor(AbsSD,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* allocate and create the DACL */
    DaclSize = sizeof(ACL) + sizeof(ACE) +
               RtlLengthSid(LocalSystemSid);
    Dacl = RtlpAllocateMemory(DaclSize,
                              'cAeS');
    if (Dacl == NULL)
    {
        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    Status = RtlCreateAcl(Dacl,
                          DaclSize,
                          ACL_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlAddAccessAllowedAceEx(Dacl,
                                      ACL_REVISION,
                                      OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
                                      STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
                                      LocalSystemSid);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* set the DACL in the security descriptor */
    Status = RtlSetDaclSecurityDescriptor(AbsSD,
                                          TRUE,
                                          Dacl,
                                          FALSE);

    /* all done */
    if (NT_SUCCESS(Status))
    {
        *SecurityDescriptor = AbsSD;
        *SystemSid = LocalSystemSid;
    }
    else
    {
Cleanup:
        if (LocalSystemSid != NULL)
        {
            RtlFreeSid(LocalSystemSid);
        }

        if (Dacl != NULL)
        {
            RtlpFreeMemory(Dacl,
                           'cAeS');
        }

        if (AbsSD != NULL)
        {
            RtlpFreeMemory(AbsSD,
                           'dSeS');
        }
    }

    return Status;
}
Example #20
0
VOID
NtfsInitializeNtfsData (
    IN PDRIVER_OBJECT DriverObject
    )

/*++

Routine Description:

    This routine initializes the global ntfs data record

Arguments:

    DriverObject - Supplies the driver object for NTFS

Return Value:

    None.

--*/

{
    USHORT FileLockMaxDepth;
    USHORT IoContextMaxDepth;
    USHORT IrpContextMaxDepth;
    USHORT KeventMaxDepth;
    USHORT ScbNonpagedMaxDepth;
    USHORT ScbSnapshotMaxDepth;

    USHORT CcbDataMaxDepth;
    USHORT CcbMaxDepth;
    USHORT DeallocatedRecordsMaxDepth;
    USHORT FcbDataMaxDepth;
    USHORT FcbIndexMaxDepth;
    USHORT IndexContextMaxDepth;
    USHORT LcbMaxDepth;
    USHORT NukemMaxDepth;
    USHORT ScbDataMaxDepth;

    PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
    BOOLEAN CapturedSubjectContext = FALSE;

    PACL SystemDacl = NULL;
    ULONG SystemDaclLength;

    PSID AdminSid = NULL;
    PSID SystemSid = NULL;
    NTSTATUS Status = STATUS_SUCCESS;

    PAGED_CODE();

    DebugTrace( +1, Dbg, ("NtfsInitializeNtfsData\n") );

    //
    //  Zero the record and set its node type code and size
    //

    RtlZeroMemory( &NtfsData, sizeof(NTFS_DATA));

    NtfsData.NodeTypeCode = NTFS_NTC_DATA_HEADER;
    NtfsData.NodeByteSize = sizeof(NTFS_DATA);

    //
    //  Initialize the queue of mounted Vcbs
    //

    InitializeListHead(&NtfsData.VcbQueue);

    //
    //  This list head keeps track of closes yet to be done.
    //

    InitializeListHead( &NtfsData.AsyncCloseList );
    InitializeListHead( &NtfsData.DelayedCloseList );

    ExInitializeWorkItem( &NtfsData.NtfsCloseItem,
                          (PWORKER_THREAD_ROUTINE)NtfsFspClose,
                          NULL );

    //
    //  Set the driver object, device object, and initialize the global
    //  resource protecting the file system
    //

    NtfsData.DriverObject = DriverObject;

    ExInitializeResource( &NtfsData.Resource );

    //
    //  Now allocate and initialize the s-list structures used as our pool
    //  of IRP context records.  The size of the zone is based on the
    //  system memory size.  We also initialize the spin lock used to protect
    //  the zone.
    //

    KeInitializeSpinLock( &NtfsData.StrucSupSpinLock );
    {

        switch ( MmQuerySystemSize() ) {

        case MmSmallSystem:

            NtfsData.FreeEresourceTotal = 14;

            //
            //  Nonpaged Lookaside list maximum depths
            //

            FileLockMaxDepth           = 8;
            IoContextMaxDepth          = 8;
            IrpContextMaxDepth         = 4;
            KeventMaxDepth             = 8;
            ScbNonpagedMaxDepth        = 8;
            ScbSnapshotMaxDepth        = 8;

            //
            //  Paged Lookaside list maximum depths
            //

            CcbDataMaxDepth            = 4;
            CcbMaxDepth                = 4;
            DeallocatedRecordsMaxDepth = 8;
            FcbDataMaxDepth            = 8;
            FcbIndexMaxDepth           = 4;
            IndexContextMaxDepth       = 8;
            LcbMaxDepth                = 4;
            NukemMaxDepth              = 8;
            ScbDataMaxDepth            = 4;

            SetFlag( NtfsData.Flags, NTFS_FLAGS_SMALL_SYSTEM );
            NtfsMaxDelayedCloseCount = MAX_DELAYED_CLOSE_COUNT;

            break;

        case MmMediumSystem:

            NtfsData.FreeEresourceTotal = 30;

            //
            //  Nonpaged Lookaside list maximum depths
            //

            FileLockMaxDepth           = 8;
            IoContextMaxDepth          = 8;
            IrpContextMaxDepth         = 8;
            KeventMaxDepth             = 8;
            ScbNonpagedMaxDepth        = 30;
            ScbSnapshotMaxDepth        = 8;

            //
            //  Paged Lookaside list maximum depths
            //

            CcbDataMaxDepth            = 12;
            CcbMaxDepth                = 6;
            DeallocatedRecordsMaxDepth = 8;
            FcbDataMaxDepth            = 30;
            FcbIndexMaxDepth           = 12;
            IndexContextMaxDepth       = 8;
            LcbMaxDepth                = 12;
            NukemMaxDepth              = 8;
            ScbDataMaxDepth            = 12;

            SetFlag( NtfsData.Flags, NTFS_FLAGS_MEDIUM_SYSTEM );
            NtfsMaxDelayedCloseCount = 4 * MAX_DELAYED_CLOSE_COUNT;

            break;

        case MmLargeSystem:

            SetFlag( NtfsData.Flags, NTFS_FLAGS_LARGE_SYSTEM );
            NtfsMaxDelayedCloseCount = 16 * MAX_DELAYED_CLOSE_COUNT;

            if (MmIsThisAnNtAsSystem()) {

                NtfsData.FreeEresourceTotal = 256;

                //
                //  Nonpaged Lookaside list maximum depths
                //

                FileLockMaxDepth           = 8;
                IoContextMaxDepth          = 8;
                IrpContextMaxDepth         = 256;
                KeventMaxDepth             = 8;
                ScbNonpagedMaxDepth        = 128;
                ScbSnapshotMaxDepth        = 8;

                //
                //  Paged Lookaside list maximum depths
                //

                CcbDataMaxDepth            = 40;
                CcbMaxDepth                = 20;
                DeallocatedRecordsMaxDepth = 8;
                FcbDataMaxDepth            = 128;
                FcbIndexMaxDepth           = 40;
                IndexContextMaxDepth       = 8;
                LcbMaxDepth                = 40;
                NukemMaxDepth              = 8;
                ScbDataMaxDepth            = 40;

            } else {

                NtfsData.FreeEresourceTotal = 128;

                //
                //  Nonpaged Lookaside list maximum depths
                //

                FileLockMaxDepth           = 8;
                IoContextMaxDepth          = 8;
                IrpContextMaxDepth         = 64;
                KeventMaxDepth             = 8;
                ScbNonpagedMaxDepth        = 64;
                ScbSnapshotMaxDepth        = 8;

                //
                //  Paged Lookaside list maximum depths
                //

                CcbDataMaxDepth            = 20;
                CcbMaxDepth                = 10;
                DeallocatedRecordsMaxDepth = 8;
                FcbDataMaxDepth            = 64;
                FcbIndexMaxDepth           = 20;
                IndexContextMaxDepth       = 8;
                LcbMaxDepth                = 20;
                NukemMaxDepth              = 8;
                ScbDataMaxDepth            = 20;
            }

            break;
        }

        NtfsMinDelayedCloseCount = NtfsMaxDelayedCloseCount * 4 / 5;

    }

    //
    //  Initialize our various lookaside lists.  To make it a bit more readable we'll
    //  define two quick macros to do the initialization
    //

#if DBG && i386 && defined (NTFSPOOLCHECK)
#define NPagedInit(L,S,T,D) { ExInitializeNPagedLookasideList( (L), NtfsDebugAllocatePoolWithTag, NtfsDebugFreePool, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#define PagedInit(L,S,T,D)  { ExInitializePagedLookasideList(  (L), NtfsDebugAllocatePoolWithTag, NtfsDebugFreePool, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#else   //  DBG && i386
#define NPagedInit(L,S,T,D) { ExInitializeNPagedLookasideList( (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#define PagedInit(L,S,T,D)  { ExInitializePagedLookasideList(  (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#endif  //  DBG && i386

    NPagedInit( &NtfsFileLockLookasideList,    sizeof(FILE_LOCK),       'kftN', FileLockMaxDepth );
    NPagedInit( &NtfsIoContextLookasideList,   sizeof(NTFS_IO_CONTEXT), 'IftN', IoContextMaxDepth );
    NPagedInit( &NtfsIrpContextLookasideList,  sizeof(IRP_CONTEXT),     'iftN', IrpContextMaxDepth );
    NPagedInit( &NtfsKeventLookasideList,      sizeof(KEVENT),          'KftN', KeventMaxDepth );
    NPagedInit( &NtfsScbNonpagedLookasideList, sizeof(SCB_NONPAGED),    'nftN', ScbNonpagedMaxDepth );
    NPagedInit( &NtfsScbSnapshotLookasideList, sizeof(SCB_SNAPSHOT),    'TftN', ScbSnapshotMaxDepth );

    PagedInit(  &NtfsCcbLookasideList,                sizeof(CCB),                 'CftN', CcbMaxDepth );
    PagedInit(  &NtfsCcbDataLookasideList,            sizeof(CCB_DATA),            'cftN', CcbDataMaxDepth );
    PagedInit(  &NtfsDeallocatedRecordsLookasideList, sizeof(DEALLOCATED_RECORDS), 'DftN', DeallocatedRecordsMaxDepth );
    PagedInit(  &NtfsFcbDataLookasideList,            sizeof(FCB_DATA),            'fftN', FcbDataMaxDepth );
    PagedInit(  &NtfsFcbIndexLookasideList,           sizeof(FCB_INDEX),           'FftN', FcbIndexMaxDepth );
    PagedInit(  &NtfsIndexContextLookasideList,       sizeof(INDEX_CONTEXT),       'EftN', IndexContextMaxDepth );
    PagedInit(  &NtfsLcbLookasideList,                sizeof(LCB),                 'lftN', LcbMaxDepth );
    PagedInit(  &NtfsNukemLookasideList,              sizeof(NUKEM),               'NftN', NukemMaxDepth );
    PagedInit(  &NtfsScbDataLookasideList,            SIZEOF_SCB_DATA,             'sftN', ScbDataMaxDepth );

    //
    //  Initialize the cache manager callback routines,  First are the routines
    //  for normal file manipulations, followed by the routines for
    //  volume manipulations.
    //

    {
        PCACHE_MANAGER_CALLBACKS Callbacks = &NtfsData.CacheManagerCallbacks;

        Callbacks->AcquireForLazyWrite  = &NtfsAcquireScbForLazyWrite;
        Callbacks->ReleaseFromLazyWrite = &NtfsReleaseScbFromLazyWrite;
        Callbacks->AcquireForReadAhead  = &NtfsAcquireScbForReadAhead;
        Callbacks->ReleaseFromReadAhead = &NtfsReleaseScbFromReadAhead;
    }

    {
        PCACHE_MANAGER_CALLBACKS Callbacks = &NtfsData.CacheManagerVolumeCallbacks;

        Callbacks->AcquireForLazyWrite  = &NtfsAcquireVolumeFileForLazyWrite;
        Callbacks->ReleaseFromLazyWrite = &NtfsReleaseVolumeFileFromLazyWrite;
        Callbacks->AcquireForReadAhead  = NULL;
        Callbacks->ReleaseFromReadAhead = NULL;
    }

    //
    //  Initialize the queue of read ahead threads
    //

    InitializeListHead(&NtfsData.ReadAheadThreads);

    //
    //  Set up global pointer to our process.
    //

    NtfsData.OurProcess = PsGetCurrentProcess();

    //
    //  Use a try-finally to cleanup on errors.
    //

    try {

        SECURITY_DESCRIPTOR NewDescriptor;
        SID_IDENTIFIER_AUTHORITY Authority = SECURITY_NT_AUTHORITY;

        SubjectContext = NtfsAllocatePool( PagedPool, sizeof( SECURITY_SUBJECT_CONTEXT ));
        SeCaptureSubjectContext( SubjectContext );
        CapturedSubjectContext = TRUE;

        //
        //  Build the default security descriptor which gives full access to
        //  system and administrator.
        //

        AdminSid = (PSID) NtfsAllocatePool( PagedPool, RtlLengthRequiredSid( 2 ));
        RtlInitializeSid( AdminSid, &Authority, 2 );
        *(RtlSubAuthoritySid( AdminSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
        *(RtlSubAuthoritySid( AdminSid, 1 )) = DOMAIN_ALIAS_RID_ADMINS;

        SystemSid = (PSID) NtfsAllocatePool( PagedPool, RtlLengthRequiredSid( 1 ));
        RtlInitializeSid( SystemSid, &Authority, 1 );
        *(RtlSubAuthoritySid( SystemSid, 0 )) = SECURITY_LOCAL_SYSTEM_RID;

        SystemDaclLength = sizeof( ACL ) +
                           (2 * sizeof( ACCESS_ALLOWED_ACE )) +
                           SeLengthSid( AdminSid ) +
                           SeLengthSid( SystemSid ) +
                           8; // The 8 is just for good measure

        SystemDacl = NtfsAllocatePool( PagedPool, SystemDaclLength );

        Status = RtlCreateAcl( SystemDacl, SystemDaclLength, ACL_REVISION2 );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlAddAccessAllowedAce( SystemDacl,
                                         ACL_REVISION2,
                                         GENERIC_ALL,
                                         SystemSid );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlAddAccessAllowedAce( SystemDacl,
                                         ACL_REVISION2,
                                         GENERIC_ALL,
                                         AdminSid );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlCreateSecurityDescriptor( &NewDescriptor,
                                              SECURITY_DESCRIPTOR_REVISION1 );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlSetDaclSecurityDescriptor( &NewDescriptor,
                                               TRUE,
                                               SystemDacl,
                                               FALSE );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = SeAssignSecurity( NULL,
                                   &NewDescriptor,
                                   &NtfsData.DefaultDescriptor,
                                   FALSE,
                                   SubjectContext,
                                   IoGetFileObjectGenericMapping(),
                                   PagedPool );

        if (!NT_SUCCESS( Status )) { leave; }

        NtfsData.DefaultDescriptorLength = RtlLengthSecurityDescriptor( NtfsData.DefaultDescriptor );

        ASSERT( SeValidSecurityDescriptor( NtfsData.DefaultDescriptorLength,
                                           NtfsData.DefaultDescriptor ));

    } finally {

        if (CapturedSubjectContext) {

            SeReleaseSubjectContext( SubjectContext );
        }

        if (SubjectContext != NULL) { NtfsFreePool( SubjectContext ); }

        if (SystemDacl != NULL) { NtfsFreePool( SystemDacl ); }

        if (AdminSid != NULL) { NtfsFreePool( AdminSid ); }

        if (SystemSid != NULL) { NtfsFreePool( SystemSid ); }
    }

    //
    //  Raise if we hit an error building the security descriptor.
    //

    if (!NT_SUCCESS( Status )) { ExRaiseStatus( Status ); }

    //
    //  And return to our caller
    //

    DebugTrace( -1, Dbg, ("NtfsInitializeNtfsData -> VOID\n") );

    return;
}
Example #21
0
File: init.c Project: GYGit/reactos
/*++
 * @name GetDosDevicesProtection
 *
 * The GetDosDevicesProtection creates a security descriptor for the DOS Devices
 * Object Directory.
 *
 * @param DosDevicesSd
 *        Pointer to the Security Descriptor to return.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
 *
 * @remarks Depending on the DOS Devices Protection Mode (set in the registry),
 *          regular users may or may not have full access to the directory.
 *
 *--*/
NTSTATUS
NTAPI
GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
{
    SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
    SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY};
    SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
    PSID WorldSid, CreatorSid, AdminSid, SystemSid;
    UCHAR KeyValueBuffer[0x40];
    PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
    UNICODE_STRING KeyName;
    ULONG ProtectionMode = 0;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PACL Dacl;
    PACCESS_ALLOWED_ACE Ace;
    HANDLE hKey;
    NTSTATUS Status;
    ULONG ResultLength, SidLength, AclLength;

    /* Create the SD */
    Status = RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION);
    ASSERT(NT_SUCCESS(Status));

    /* Initialize the System SID */
    Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
                                         SECURITY_LOCAL_SYSTEM_RID,
                                         0, 0, 0, 0, 0, 0, 0,
                                         &SystemSid);
    ASSERT(NT_SUCCESS(Status));

    /* Initialize the World SID */
    Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1,
                                         SECURITY_WORLD_RID,
                                         0, 0, 0, 0, 0, 0, 0,
                                         &WorldSid);
    ASSERT(NT_SUCCESS(Status));

    /* Initialize the Admin SID */
    Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 2,
                                         SECURITY_BUILTIN_DOMAIN_RID,
                                         DOMAIN_ALIAS_RID_ADMINS,
                                         0, 0, 0, 0, 0, 0,
                                         &AdminSid);
    ASSERT(NT_SUCCESS(Status));

    /* Initialize the Creator SID */
    Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
                                         SECURITY_CREATOR_OWNER_RID,
                                         0, 0, 0, 0, 0, 0, 0,
                                         &CreatorSid);
    ASSERT(NT_SUCCESS(Status));

    /* Open the Session Manager Key */
    RtlInitUnicodeString(&KeyName, SM_REG_KEY);
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
    if (NT_SUCCESS(Status))
    {
        /* Read the key value */
        RtlInitUnicodeString(&KeyName, L"ProtectionMode");
        Status = NtQueryValueKey(hKey,
                                 &KeyName,
                                 KeyValuePartialInformation,
                                 KeyValueBuffer,
                                 sizeof(KeyValueBuffer),
                                 &ResultLength);

        /* Make sure it's what we expect it to be */
        KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
        if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
            (*(PULONG)KeyValuePartialInfo->Data))
        {
            /* Save the Protection Mode */
            ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
        }

        /* Close the handle */
        NtClose(hKey);
    }

    /* Check the Protection Mode */
    if (ProtectionMode & 3)
    {
        /* Calculate SID Lengths */
        SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) +
                    RtlLengthSid(AdminSid);
        AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;

        /* Allocate memory for the DACL */
        Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
        ASSERT(Dacl != NULL);

        /* Build the ACL and add 3 ACEs */
        Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
        ASSERT(NT_SUCCESS(Status));
        Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
        ASSERT(NT_SUCCESS(Status));
        Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid);
        ASSERT(NT_SUCCESS(Status));
        Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid);
        ASSERT(NT_SUCCESS(Status));

        /* Edit the ACEs to make them inheritable */
        Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace);
        ASSERT(NT_SUCCESS(Status));
        Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
        Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace);
        ASSERT(NT_SUCCESS(Status));
        Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
        Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
        ASSERT(NT_SUCCESS(Status));
        Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;

        /* Set this DACL with the SD */
        Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
        ASSERT(NT_SUCCESS(Status));
        goto Quickie;
    }
    else
    {
        /* Calculate SID Lengths */
        SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid);
        AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;

        /* Allocate memory for the DACL */
        Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
        ASSERT(Dacl != NULL);

        /* Build the ACL and add 3 ACEs */
        Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
        ASSERT(NT_SUCCESS(Status));
        Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid);
        ASSERT(NT_SUCCESS(Status));
        Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
        ASSERT(NT_SUCCESS(Status));
        Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid);
        ASSERT(NT_SUCCESS(Status));

        /* Edit the last ACE to make it inheritable */
        Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
        ASSERT(NT_SUCCESS(Status));
        Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;

        /* Set this DACL with the SD */
        Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
        ASSERT(NT_SUCCESS(Status));
        goto Quickie;
    }

/* FIXME: failure cases! Fail: */
    /* Free the memory */
    RtlFreeHeap(CsrHeap, 0, Dacl);

/* FIXME: semi-failure cases! Quickie: */
Quickie:
    /* Free the SIDs */
    RtlFreeSid(CreatorSid);
    RtlFreeSid(AdminSid);
    RtlFreeSid(WorldSid);
    RtlFreeSid(SystemSid);

    /* Return */
    return Status;
}
// Sets the access-control list for a handle to "Everyone:AccessMask"
// The handle must be open for WRITE_DAC access
static NTSTATUS NtSetObjectAccessForEveryone(
    IN HANDLE ObjectHandle,
    IN ACCESS_MASK AccessMask)
{
    SID_IDENTIFIER_AUTHORITY SiaEveryone = SECURITY_WORLD_SID_AUTHORITY;
    SECURITY_DESCRIPTOR sd;
    NTSTATUS Status;
    ULONG cbAclLength = 0;
    PSID pSidEveryone = NULL; 
    PACL pAcl = NULL;

    // Get the SID of Everyone
    Status = RtlAllocateAndInitializeSid(&SiaEveryone, 1, 0, 0, 0, 0, 0, 0, 0, 0, &pSidEveryone);

    // Allocate space for ACL
    if(NT_SUCCESS(Status))
    {
        ULONG dwSidLength = RtlLengthSid(pSidEveryone);

        // Create ACL for full access to the file
        cbAclLength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + dwSidLength - sizeof(DWORD);
        pAcl = (PACL)RtlAllocateHeap(RtlProcessHeap(), 0, cbAclLength);
        if(pAcl == NULL)
            Status = STATUS_INSUFFICIENT_RESOURCES;
    }

    // Create the Access control list with one ACE
    if(NT_SUCCESS(Status))
    {
        Status = RtlCreateAcl(pAcl, cbAclLength, ACL_REVISION);
    }

    // Add the ACE to the ACL
    if(NT_SUCCESS(Status))
    {
        Status = RtlAddAccessAllowedAce(pAcl, ACL_REVISION, AccessMask, pSidEveryone);
    }

    // Initialize the blank security descriptor
    if(NT_SUCCESS(Status))
    {
        Status = RtlCreateSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
    }

    // Set the ACL to the security descriptor
    if(NT_SUCCESS(Status))
    {
        Status = RtlSetDaclSecurityDescriptor(&sd, TRUE, pAcl, FALSE);
    }

    // Apply the security information to the handle
    if(NT_SUCCESS(Status))
    {
        Status = NtSetSecurityObject(ObjectHandle, DACL_SECURITY_INFORMATION, &sd);
    }

    // Free buffers
    if(pAcl != NULL)
        RtlFreeHeap(RtlProcessHeap(), 0, pAcl);
    if(pSidEveryone != NULL)
        RtlFreeSid(pSidEveryone);
    return Status;
}
Example #23
0
PSECURITY_DESCRIPTOR
NTAPI
INIT_FUNCTION
CmpHiveRootSecurityDescriptor(VOID)
{
    NTSTATUS Status;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    PACL Acl, AclCopy;
    PSID Sid[4];
    SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
    SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
    ULONG AceLength, AclLength, SidLength;
    PACE_HEADER AceHeader;
    ULONG i;
    PAGED_CODE();

    /* Phase 1: Allocate SIDs */
    SidLength = RtlLengthRequiredSid(1);
    Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
    Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
    Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
    SidLength = RtlLengthRequiredSid(2);
    Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);

    /* Make sure all SIDs were allocated */
    if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
    {
        /* Bugcheck */
        KeBugCheckEx(REGISTRY_ERROR, 11, 1, 0, 0);
    }

    /* Phase 2: Initialize all SIDs */
    Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1);
    Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);
    Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);
    Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 2, 0, 0);

    /* Phase 2: Setup SID Sub Authorities */
    *RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;
    *RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID;
    *RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID;
    *RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID;
    *RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;

    /* Make sure all SIDs are valid */
    ASSERT(RtlValidSid(Sid[0]));
    ASSERT(RtlValidSid(Sid[1]));
    ASSERT(RtlValidSid(Sid[2]));
    ASSERT(RtlValidSid(Sid[3]));

    /* Phase 3: Calculate ACL Length */
    AclLength = sizeof(ACL);
    for (i = 0; i < 4; i++)
    {
        /* This is what MSDN says to do */
        AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
        AceLength += SeLengthSid(Sid[i]);
        AclLength += AceLength;
    }

    /* Phase 3: Allocate the ACL */
    Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);
    if (!Acl) KeBugCheckEx(REGISTRY_ERROR, 11, 3, 0, 0);

    /* Phase 4: Create the ACL */
    Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 4, Status, 0);

    /* Phase 5: Build the ACL */
    Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]);
    Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]);
    Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);
    Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 5, Status, 0);

    /* Phase 5: Make the ACEs inheritable */
    Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
    Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
    Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
    Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;

    /* Phase 6: Allocate the security descriptor and make space for the ACL */
    SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
                                               sizeof(SECURITY_DESCRIPTOR) +
                                               AclLength,
                                               TAG_CM);
    if (!SecurityDescriptor) KeBugCheckEx(REGISTRY_ERROR, 11, 6, 0, 0);

    /* Phase 6: Make a copy of the ACL */
    AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);
    RtlCopyMemory(AclCopy, Acl, AclLength);

    /* Phase 7: Create the security descriptor */
    Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 7, Status, 0);

    /* Phase 8: Set the ACL as a DACL */
    Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
                                          TRUE,
                                          AclCopy,
                                          FALSE);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 8, Status, 0);

    /* Free the SIDs and original ACL */
    for (i = 0; i < 4; i++) ExFreePoolWithTag(Sid[i], TAG_CM);
    ExFreePoolWithTag(Acl, TAG_CM);

    /* Return the security descriptor */
    return SecurityDescriptor;
}
Example #24
0
ULONG CreateSecurityDescriptor(
    ULONG *pSecurityDescriptor,
    PSID *ppWorldSid,
    ACCESS_MASK AccessMask)
{
    ULONG rc = 0L;                     /* return code */
    PACL pAclBuffer;                   /* ptr to ACL buffer */
    ULONG SidLength;                   /* length of SID - 1 sub authority */
    PSID pWSid;                        /* ptr to world SID */
    SID_IDENTIFIER_AUTHORITY SidAuth = SECURITY_WORLD_SID_AUTHORITY;


    /*
     *  Create World SID.
     */
    SidLength = RtlLengthRequiredSid(1);

    if ((pWSid = (PSID)RtlAllocateHeap(RtlProcessHeap(),
                                       MAKE_TAG( TMP_TAG ) | HEAP_ZERO_MEMORY,
                                       SidLength)) == NULL)
    {
        *ppWorldSid = NULL;
        KdPrint(("NLSAPI (BaseSrv): Could NOT Allocate SID Buffer.\n"));
        return (ERROR_OUTOFMEMORY);
    }
    *ppWorldSid = pWSid;

    RtlInitializeSid(pWSid, &SidAuth, 1);

    *(RtlSubAuthoritySid(pWSid, 0)) = SECURITY_WORLD_RID;

    /*
     *  Initialize Security Descriptor.
     */
    rc = RtlCreateSecurityDescriptor(pSecurityDescriptor,
                                     SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(rc))
    {
        KdPrint(("NLSAPI (BaseSrv): Could NOT Create Security Descriptor - %lx.\n",
                 rc));
        RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid);
        return (rc);
    }

    /*
     *  Initialize ACL.
     */
    pAclBuffer = (PACL)((PBYTE)pSecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
    rc = RtlCreateAcl((PACL)pAclBuffer,
                      MAX_PATH_LEN * sizeof(ULONG),
                      ACL_REVISION2);
    if (!NT_SUCCESS(rc))
    {
        KdPrint(("NLSAPI (BaseSrv): Could NOT Create ACL - %lx.\n", rc));
        RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid);
        return (rc);
    }

    /*
     *  Add an ACE to the ACL that allows World GENERIC_READ to the
     *  section object.
     */
    rc = RtlAddAccessAllowedAce((PACL)pAclBuffer,
                                ACL_REVISION2,
                                AccessMask,
                                pWSid);
    if (!NT_SUCCESS(rc))
    {
        KdPrint(("NLSAPI (BaseSrv): Could NOT Add Access Allowed ACE - %lx.\n",
                 rc));
        RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid);
        return (rc);
    }

    /*
     *  Assign the DACL to the security descriptor.
     */
    rc = RtlSetDaclSecurityDescriptor((PSECURITY_DESCRIPTOR)pSecurityDescriptor,
                                      (BOOLEAN)TRUE,
                                      (PACL)pAclBuffer,
                                      (BOOLEAN)FALSE);
    if (!NT_SUCCESS(rc))
    {
        KdPrint(("NLSAPI (BaseSrv): Could NOT Set DACL Security Descriptor - %lx.\n",
                 rc));
        RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid);
        return (rc);
    }

    /*
     *  Return success.
     */
    return (NO_ERROR);
}
Example #25
0
void  ApfInitDll ()
{
    NTSTATUS Status;		
    DWORD ulInitElapsedTime;
    SHORT sInitTimerHandle;
	DWORD ARGS64;

#ifdef CALIBDBG
    SHORT sTimerHandle;
    ULONG ulElapsedTime;
#endif

#ifdef ERRORDBG
    DWORD Error;
#endif


    int   i;
    STRING DataSemName;
    UNICODE_STRING DataSemUnicodeName;
    OBJECT_ATTRIBUTES DataSemAttributes;


    // Create public share security descriptor for all the named objects
    //
    Status = RtlCreateSecurityDescriptor (
		&SecDescriptor,
		SECURITY_DESCRIPTOR_REVISION1
		);
#ifdef ERRORDBG
    if (!NT_SUCCESS(Status)) {
	KdPrint (("WAP: RtlCreateSecurityDescriptor falied - 0x%lx\n", Status));
    }
#endif

    Status = RtlSetDaclSecurityDescriptor (
		&SecDescriptor,	   // SecurityDescriptor
		TRUE,		   // DaclPresent
		NULL,		   // Dacl
		FALSE		   // DaclDefaulted
                );
#ifdef ERRORDBG
    if (!NT_SUCCESS(Status)) {
	KdPrint (("WAP: RtlSetDaclSecurityDescriptor falied - 0x%lx\n", Status));
    }
#endif

    // Create sections for data and api arrays
    //
    if ( NT_SUCCESS(ApfCreateDataSection(&ApfControl)) ) {

	// Leave room for control flag
	//
	ApfData = (PAPFDATA)(ApfControl+1);
		
	// Initialization for semaphore creation
	//
	RtlInitString(&DataSemName, DATA_SEM_NAME);
			
	Status = RtlAnsiStringToUnicodeString(
		     &DataSemUnicodeName,
		     &DataSemName,
		     TRUE);
			
	if (NT_SUCCESS(Status)) {
		InitializeObjectAttributes(
			&DataSemAttributes,
			&DataSemUnicodeName,
			OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
			NULL,
			&SecDescriptor);
	}

	// Create semaphores
	//
	Status = NtCreateSemaphore(
			&hDataSem,
			SEMAPHORE_QUERY_STATE |
			SEMAPHORE_MODIFY_STATE |
			SYNCHRONIZE,
			&DataSemAttributes,
			1L,
			1L);

#ifdef ERRORDBG
	if (!NT_SUCCESS(Status)) {
	    KdPrint (("WAP: Data semaphore creation falied %lx\n",
		Status));
	}
#endif

	// Get semaphores
	//
	Status = NtWaitForSingleObject(hDataSem,FALSE,NULL);
#ifdef ERRORDBG
	if (!NT_SUCCESS(Status)) {
	    KdPrint (("WAP: Could not wait for Dsemaphore in ApfInitDll, %lx\n",
		Status));
	}
#endif

	//
	// Do timer calibration if not already done.
	//
	if (!ApfControl->fCalibrate) {

	    ApfControl->fCalibrate = TRUE;

	    //
	    //	 Calibrate time overheads:
        //   we get the minimum time here, to avoid extra time from
        //   interrupts etc.
        //   the tedious approach has two benefits
        //   - duplicate generated code as accurately as possible
        //   - pick up timer overhead, that isn't handled correctly
	    //	 in timer
        //   NOTE: ApfData[I_CALIBRATE].ulMinTime contains the
	    //	       timer overhead, while ApfData[I_CALIBRATE].cCalls
	    //	       contains the number of processess accessing this
	    //	       DLL.
		//
	    ApfData[I_CALIBRATE].cCalls = 0L;
        ApfData[I_CALIBRATE].cTimingErrors = 0L;
	    ApfData[I_CALIBRATE].ulTotalTime = 0L;
	    ApfData[I_CALIBRATE].ulFirstTime = MAX_LONG;
	    ApfData[I_CALIBRATE].ulMaxTime = MAX_LONG;
        ApfData[I_CALIBRATE].ulMinTime = MAX_LONG;

	    ApfClearData();

		TimerOpen(&sInitTimerHandle, MICROSECONDS);
#ifdef CALIBDBG
		// Release semaphore
		//
		Status = NtReleaseSemaphore(hDataSem,1,NULL);
#ifdef ERRORDBG
		if (!NT_SUCCESS(Status)) {
			KdPrint (("WAP: DSemaphore Not Released in ApfInitDll!! %lx\n",
				Status));
		}
#endif
		//
		// Overhead for all the API wrapper code
		// Stored in ApfData[I_CALIBRATE].ulMaxTime
		// Used for debugging - for WOW profiling overhead.
		//
		for (i=0; i<NUM_ITRATIONS; i++) {
			TimerInit(sInitTimerHandle);
			if (fInitDone == FALSE) {
			}
			TimerOpen(&sTimerHandle, MICROSECONDS);
			TimerInit(sTimerHandle);
			//
			// Get the elapsed time
			//
			ulElapsedTime = TimerRead(sTimerHandle);
			ApfRecordInfo(1, ulElapsedTime);
			TimerClose(sTimerHandle);
			ulInitElapsedTime = TimerRead(sInitTimerHandle);
			if ((ulInitElapsedTime < ApfData[I_CALIBRATE].ulMaxTime) &&
				(ulInitElapsedTime > MIN_ACCEPTABLEOVERHEAD)) {
				ApfData[I_CALIBRATE].ulMaxTime = ulInitElapsedTime;
			}
		}

		// Get semaphores
		//
		Status = NtWaitForSingleObject(hDataSem,FALSE,NULL);
#ifdef ERRORDBG
		if (!NT_SUCCESS(Status)) {
			KdPrint (("WAP: Could not wait for Dsemaphore in ApfInitDll, %lx\n",
			Status));
		}
#endif
#endif
		//
		// Excess overhead for TimerInit() followed by TimerREad() calls
		// Stored in ApfData[I_CALIBRATE].ulMinTime
		// Used by all APIs
		//
	    for (i=0; i<NUM_ITRATIONS; i++) {
			TimerInit(sInitTimerHandle);
			ulInitElapsedTime = TimerRead(sInitTimerHandle);
			if ((ulInitElapsedTime < ApfData[I_CALIBRATE].ulMinTime) &&
				(ulInitElapsedTime > MIN_ACCEPTABLEOVERHEAD)) {
				ApfData[I_CALIBRATE].ulMinTime = ulInitElapsedTime;
			}
	    }
		//
		// Oerhead for calling cdecl APIs with 64 DWORD arguments
		// Stored in ApfData[I_CALIBRATE].ulFirstTime
		// Used by all variable argument cdecl APIs such as wsprintf()
		//
	    for (i=0; i<NUM_ITRATIONS; i++) {
			TimerInit(sInitTimerHandle);
			CalibCdeclApi (ARGS64);
			ulInitElapsedTime = TimerRead(sInitTimerHandle);
			if ((ulInitElapsedTime < ApfData[I_CALIBRATE].ulFirstTime) &&
				(ulInitElapsedTime > MIN_ACCEPTABLEOVERHEAD)) {
				ApfData[I_CALIBRATE].ulFirstTime = ulInitElapsedTime;
			}
	    }
		ApfData[I_CALIBRATE].ulFirstTime -= ApfData[I_CALIBRATE].ulMinTime;
		TimerClose(sInitTimerHandle);	
	}

	// Increment the number of active processes on this DLL
	//
	ApfData[I_CALIBRATE].cCalls++;
	
	// Load the module being profiled
    //
	hModule=GetModuleHandle(MODULE_NAME);
#ifdef ERRORDBG
	if (hModule==NULL) {
	    Error=GetLastError();
	    KdPrint (("WAP: Module Handle is null - %lx\n",Error));
	}
#endif
	// Release semaphore
	//
	Status = NtReleaseSemaphore(hDataSem,1,NULL);
#ifdef ERRORDBG
	if (!NT_SUCCESS(Status)) {
	    KdPrint (("WAP: DSemaphore Not Released in ApfInitDll!! %lx\n",
		    Status));
	}
#endif
        fInitDone = TRUE;
    }
#ifdef ERRORDBG
    else {
	KdPrint (("WAP: Couldn't create DATA section in ApfInitDll\n"));
    }
#endif


} /* ApfInitDll () */
Example #26
0
BOOLEAN
SeRmInitPhase1(
    )

/*++

Routine Description:

    This function is called by Phase 1 System Initialization to initialize
    the Security Reference Monitor.  Note that initialization of the
    Reference Monitor Global State has already been performed in Phase 0
    initialization to allow access validation routines to operate without
    having to check that Reference Monitor Initialization is complete.

    The steps listed below are performed in this routine.  The remainder
    of Reference Monitor initialization requires the LSA subsystem to have run,
    so that initialization is performed in a separate thread (the RM Command
    Server Thread, see below), so that the present thread can create the
    Session Manager which execs the LSA.

    o Create the Reference Monitor Command LPC port.  The LSA subsystem sends
      commands (e.g. turn on auditing) which change the Reference Monitor
      Global State.
    o Create an Event for use in synchronizing with the LSA subsystem.  The
      LSA will signal the event when the portion of LSA initialization upon
      with the Reference Monitor depends is complete.  The Reference Monitor
      uses another LPC port, called the LSA Command Port to send commands
      to the LSA, so the RM must know that this port has been created before
      trying to connect to it.
    o Create the Reference Monitor Command Server Thread.  This thread is
      a permanent thread of the System Init process that fields the Reference
      Monitor State Change commands described above.


Arguments:

    None.

Return Value:

    BOOLEAN - TRUE if Rm Initialization (Phase 1) succeeded, else FALSE

--*/

{
    NTSTATUS Status;
    STRING RmCommandPortName;
    UNICODE_STRING UnicodeRmCommandPortName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    STRING LsaInitEventName;
    UNICODE_STRING UnicodeLsaInitEventName;
    OBJECT_ATTRIBUTES LsaInitEventObjectAttributes;
    SECURITY_DESCRIPTOR LsaInitEventSecurityDescriptor;
    ULONG AclSize;

    PAGED_CODE();

    //
    // Create an LPC port called the Reference Monitor Command Port.
    // This will be used by the LSA to send commands to the Reference
    // Monitor to update its state data.
    //

    RtlInitString( &RmCommandPortName, "\\SeRmCommandPort" );
    Status = RtlAnsiStringToUnicodeString(
                 &UnicodeRmCommandPortName,
                 &RmCommandPortName,
                 TRUE );  ASSERT( NT_SUCCESS(Status) );
    InitializeObjectAttributes(
        &ObjectAttributes,
        &UnicodeRmCommandPortName,
        0,
        NULL,
        NULL
        );

    Status = ZwCreatePort(
                 &SepRmState.RmCommandPortHandle,
                 &ObjectAttributes,
                 sizeof(SEP_RM_CONNECT_INFO),
                 sizeof(RM_COMMAND_MESSAGE),
                 sizeof(RM_COMMAND_MESSAGE) * 32
                 );
    RtlFreeUnicodeString( &UnicodeRmCommandPortName );

    if( !NT_SUCCESS(Status) ) {

        KdPrint(("Security: Rm Create Command Port failed 0x%lx\n", Status));
        return FALSE;
    }

    //
    // Prepare to create an event for synchronizing with the LSA.
    // First, build the Security Descriptor for the Init Event Object
    //

    Status = RtlCreateSecurityDescriptor(
                 &LsaInitEventSecurityDescriptor,
                 SECURITY_DESCRIPTOR_REVISION
                 );

    if (!NT_SUCCESS(Status)) {

        KdPrint(("Security:  Creating Lsa Init Event Desc failed 0x%lx\n",
                  Status));
        return FALSE;
    }

    //
    // Allocate a temporary buffer from the paged pool.  It is a fatal
    // system error if the allocation fails since security cannot be
    // enabled.
    //

    AclSize = sizeof(ACL) +
              sizeof(ACCESS_ALLOWED_ACE) +
              SeLengthSid(SeLocalSystemSid);
    LsaInitEventSecurityDescriptor.Dacl =
        ExAllocatePoolWithTag(PagedPool, AclSize, 'cAeS');

    if (LsaInitEventSecurityDescriptor.Dacl == NULL) {

        KdPrint(("Security LSA:  Insufficient resources to initialize\n"));
        return FALSE;
    }

    //
    // Now create the Discretionary ACL within the Security Descriptor
    //

    Status = RtlCreateAcl(
                 LsaInitEventSecurityDescriptor.Dacl,
                 AclSize,
                 ACL_REVISION2
                 );

    if (!NT_SUCCESS(Status)) {

        KdPrint(("Security:  Creating Lsa Init Event Dacl failed 0x%lx\n",
                  Status));
        return FALSE;
    }

    //
    // Now add an ACE giving GENERIC_ALL access to the User ID
    //

    Status = RtlAddAccessAllowedAce(
                 LsaInitEventSecurityDescriptor.Dacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeLocalSystemSid
                 );

    if (!NT_SUCCESS(Status)) {

        KdPrint(("Security:  Adding Lsa Init Event ACE failed 0x%lx\n",
                  Status));
        return FALSE;
    }

    //
    // Set up the Object Attributes for the Lsa Initialization Event
    //

    RtlInitString( &LsaInitEventName, "\\SeLsaInitEvent" );
    Status = RtlAnsiStringToUnicodeString(
                 &UnicodeLsaInitEventName,
                 &LsaInitEventName,
                 TRUE );  ASSERT( NT_SUCCESS(Status) );
    InitializeObjectAttributes(
        &LsaInitEventObjectAttributes,
        &UnicodeLsaInitEventName,
        0,
        NULL,
        &LsaInitEventSecurityDescriptor
        );

    //
    // Create an event for use in synchronizing with the LSA.  The LSA will
    // signal this event when LSA initialization has reached the point
    // where the LSA's Reference Monitor Server Port has been created.
    //

    Status = ZwCreateEvent(
                 &(SepRmState.LsaInitEventHandle),
                 EVENT_MODIFY_STATE,
                 &LsaInitEventObjectAttributes,
                 NotificationEvent,
                 FALSE);

    RtlFreeUnicodeString( &UnicodeLsaInitEventName );

    if (!NT_SUCCESS(Status)) {

        KdPrint(("Security: LSA init event creation failed.0x%xl\n",
            Status));
        return FALSE;
    }

    //
    // Deallocate the pool memory used for the Init Event DACL
    //

    ExFreePool( LsaInitEventSecurityDescriptor.Dacl );

    //
    // Create a permanent thread of the Sysinit Process, called the
    // Reference Monitor Server Thread.  This thread is dedicated to
    // receiving Reference Monitor commands and dispatching them.
    //

    Status = PsCreateSystemThread(
                 &SepRmState.SepRmThreadHandle,
                 THREAD_GET_CONTEXT |
                 THREAD_SET_CONTEXT |
                 THREAD_SET_INFORMATION,
                 NULL,
                 NULL,
                 NULL,
                 SepRmCommandServerThread,
                 NULL
                 );

    if (!NT_SUCCESS(Status)) {

        KdPrint(("Security: Rm Server Thread creation failed 0x%lx\n", Status));
        return FALSE;
    }

    //
    // Initialize data from the registry.  This must go here because all other
    // Se initialization takes place before the registry is initialized.
    //

    SepAdtInitializeCrashOnFail();
    SepAdtInitializePrivilegeAuditing();
    SepAdtInitializeAuditingOptions();
    
    //
    // Reference Monitor initialization is successful if we get to here.
    //

    ZwClose( SepRmState.SepRmThreadHandle );
    SepRmState.SepRmThreadHandle = NULL;
    return TRUE;
}
// Takes ownership on handle (file or registry key).
// The handle must be open for WRITE_OWNER access
static NTSTATUS NtTakeOwnershipObject(HANDLE ObjectHandle)
{
    SECURITY_DESCRIPTOR sd;
    PTOKEN_USER pTokenUser = NULL;
    NTSTATUS Status;
    HANDLE TokenHandle = NULL;
    ULONG cbTokenUser = 0;

    // Open the token of the current process
    Status = NtOpenProcessToken(NtCurrentProcess(),
                                TOKEN_QUERY,
                               &TokenHandle);
    if(NT_SUCCESS(Status))
    {
        NtQueryInformationToken(TokenHandle, 
                                TokenUser,
                                pTokenUser,
                                cbTokenUser,
                               &cbTokenUser);
        if(cbTokenUser == 0)
        {
            NtClose(TokenHandle);
            return STATUS_UNSUCCESSFUL;
        }

        pTokenUser = (PTOKEN_USER)RtlAllocateHeap(RtlProcessHeap(), 0, cbTokenUser);
        if(pTokenUser != NULL)
        {
            Status = NtQueryInformationToken(TokenHandle, 
                                             TokenUser,
                                             pTokenUser,
                                             cbTokenUser,
                                            &cbTokenUser);
        }
        else
        {
            Status = STATUS_NO_MEMORY;
        }
    }

    // Initialize the blank security descriptor
    if(NT_SUCCESS(Status))
    {
        Status = RtlCreateSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
    }

    // Set the owner to the security descriptor
    if(NT_SUCCESS(Status))
    {
        Status = RtlSetOwnerSecurityDescriptor(&sd, pTokenUser->User.Sid, FALSE);
    }

    // Apply the owner to the object handle
    if(NT_SUCCESS(Status))
    {
        Status = NtSetSecurityObject(ObjectHandle, OWNER_SECURITY_INFORMATION, &sd);
    }

    // Free buffers
    if(pTokenUser != NULL)
        RtlFreeHeap(RtlProcessHeap(), 0, pTokenUser);
    if(TokenHandle != NULL)
        NtClose(TokenHandle);
    return Status;
}
Example #28
0
VOID
SepInitProcessAuditSd( VOID )
/*++

Routine Description:

    This function initializes SepProcessAuditSd -- a security descriptor
    that is used by SepAddSaclToProcess to add SACL to the existing
    security descriptor on a system process.

    A system process is defined as the one whose token has at least
    one of the following sids.
    -- SeLocalSystemSid
    -- SeLocalServiceSid
    -- SeNetworkServiceSid

Arguments:

    None.

Return Value:

    None.


--*/
{
#define PROCESS_ACCESSES_TO_AUDIT ( PROCESS_CREATE_THREAD   |\
                                    PROCESS_SET_INFORMATION |\
                                    PROCESS_SET_PORT        |\
                                    PROCESS_SUSPEND_RESUME )

    NTSTATUS Status = STATUS_SUCCESS;
    ULONG AclLength, TotalSdLength;
    PISECURITY_DESCRIPTOR Sd = NULL;
    PISECURITY_DESCRIPTOR Sd2 = NULL;
    PACL Acl = NULL;

    //
    // free earlier instance if present
    //

    if ( SepProcessAuditSd != NULL ) {

        ExFreePool( SepProcessAuditSd );
        SepProcessAuditSd = NULL;
    }

    //
    // Don't initialize SeProcessAuditSd if SepProcessAccessesToAudit is 0
    // This effectively disables process access auditing
    //

    if ( SepProcessAccessesToAudit == 0 ) {

        goto Cleanup;
    }

    AclLength = (ULONG)sizeof(ACL) +
        ((ULONG)sizeof(SYSTEM_AUDIT_ACE) - sizeof(ULONG)) +
        SeLengthSid( SeWorldSid );

    TotalSdLength = sizeof(SECURITY_DESCRIPTOR) + AclLength;

    Sd = (PSECURITY_DESCRIPTOR) ExAllocatePoolWithTag(
                                    NonPagedPool,
                                    TotalSdLength,
                                    'cAeS');

    if ( Sd == NULL ) {

        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Cleanup;
    }

    Acl = (PACL) (Sd + 1);

    Status = RtlCreateAcl( Acl, AclLength, ACL_REVISION2 );

    if ( NT_SUCCESS( Status )) {

        Status = RtlAddAuditAccessAce(
                     Acl,
                     ACL_REVISION2,
                     SepProcessAccessesToAudit,
                     SeWorldSid,
                     TRUE,
                     TRUE
                     );

        if ( NT_SUCCESS( Status )) {

            Status = RtlCreateSecurityDescriptor( Sd,
                                                  SECURITY_DESCRIPTOR_REVISION1 );
            if ( NT_SUCCESS( Status )) {

                Status = RtlSetSaclSecurityDescriptor( Sd,
                                                       TRUE, Acl, FALSE );
                if ( NT_SUCCESS( Status )) {

                    SepProcessAuditSd = Sd;
                }
            }
        }
    }

    ASSERT( NT_SUCCESS(Status) );

    if ( !NT_SUCCESS( Status )) {

        goto Cleanup;
    }

    //
    // create and initialize SepImportantProcessSd
    //

    AclLength = (ULONG)sizeof(ACL) +
        (3*((ULONG)sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG))) +
        SeLengthSid( SeLocalSystemSid ) +
        SeLengthSid( SeLocalServiceSid ) +
        SeLengthSid( SeNetworkServiceSid );

    TotalSdLength = sizeof(SECURITY_DESCRIPTOR) + AclLength;

    Sd2 = (PSECURITY_DESCRIPTOR) ExAllocatePoolWithTag(
                                    NonPagedPool,
                                    TotalSdLength,
                                    'cAeS');

    if ( Sd2 == NULL ) {

        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Cleanup;
    }

    Acl = (PACL) (Sd2 + 1);

    Status = RtlCreateAcl( Acl, AclLength, ACL_REVISION2 );

    if ( NT_SUCCESS( Status )) {

        Status = RtlAddAccessAllowedAce(
                     Acl,
                     ACL_REVISION2,
                     SEP_QUERY_MEMBERSHIP,
                     SeLocalSystemSid
                     );

        if ( !NT_SUCCESS( Status )) {

            goto Cleanup;
        }

        Status = RtlAddAccessAllowedAce(
                     Acl,
                     ACL_REVISION2,
                     SEP_QUERY_MEMBERSHIP,
                     SeLocalServiceSid
                     );

        if ( !NT_SUCCESS( Status )) {

            goto Cleanup;
        }


        Status = RtlAddAccessAllowedAce(
                     Acl,
                     ACL_REVISION2,
                     SEP_QUERY_MEMBERSHIP,
                     SeNetworkServiceSid
                     );

        if ( !NT_SUCCESS( Status )) {

            goto Cleanup;
        }

        Status = RtlCreateSecurityDescriptor( Sd2, SECURITY_DESCRIPTOR_REVISION1 );

        if ( NT_SUCCESS( Status )) {

            Status = RtlSetDaclSecurityDescriptor( Sd2, TRUE, Acl, FALSE );

            if ( NT_SUCCESS( Status )) {

                SepImportantProcessSd = Sd2;
            }
        }
    }


 Cleanup:

    if ( !NT_SUCCESS( Status )) {

        ASSERT( FALSE && L"SepInitProcessAuditSd failed" );

        //
        // this will bugcheck if SepCrashOnAuditFail is TRUE
        //

        SepAuditFailed( Status );

        if ( Sd ) {

            ExFreePool( Sd );
            Sd = NULL;
            SepProcessAuditSd = NULL;
        }
        if ( Sd2 ) {

            ExFreePool( Sd2 );
            Sd2 = NULL;
            SepImportantProcessSd = NULL;
        }
    }
}
Example #29
0
//----------------------------------------------------------------------
//
// NTIMakeAbsoluteSD
//
// Takes a self-relative security descriptor and returns an allocated
// absolute version. Caller is responsibile for freeing the allocated
// buffer on success.
// 
//----------------------------------------------------------------------
NTSTATUS NTIMakeAbsoluteSD( PSECURITY_DESCRIPTOR RelSecurityDescriptor, 
			    PSECURITY_DESCRIPTOR *pAbsSecurityDescriptor )
{
   NTSTATUS		status;
   BOOLEAN		DaclPresent, DaclDefaulted, OwnerDefaulted, GroupDefaulted;
   PACL			Dacl;
   PSID			Owner, Group;
   PSECURITY_DESCRIPTOR	 absSecurityDescriptor;

   //
   // Initialize buffer pointers
   //
   absSecurityDescriptor = (PSECURITY_DESCRIPTOR) ExAllocatePool( NonPagedPool, 1024 );
   *pAbsSecurityDescriptor = absSecurityDescriptor;

   //
   // Create an absolute-form security descriptor for manipulation.
   // The one on the security descriptor is in self-relative form.
   //
   status = RtlCreateSecurityDescriptor( absSecurityDescriptor,
					 SECURITY_DESCRIPTOR_REVISION );
   if( !NT_SUCCESS( status ) ) {

	  DbgPrint(("Secsys: Unable to initialize security descriptor\n"));
	  goto cleanup;
   }

   //
   // Locate the descriptor's DACL and apply the DACL to the new 
   // descriptor we're going to modify
   //
   status = RtlGetDaclSecurityDescriptor( RelSecurityDescriptor,
					  &DaclPresent,
					  &Dacl,
					  &DaclDefaulted );
   if( !NT_SUCCESS( status ) || !DaclPresent ) {

     if( !NT_SUCCESS( status )) {

       DbgPrint(("Secsys: Error obtaining security descriptor's DACL: %x\n", status ));

     } else {

       DbgPrint(("Secsys: Security descriptor does not have a DACL\n" ));
     }

     goto cleanup;
   }

   status = RtlSetDaclSecurityDescriptor( absSecurityDescriptor,
					  DaclPresent,
					  Dacl,
					  DaclDefaulted );
   if( !NT_SUCCESS( status )) {

     DbgPrint(("Secsys: Coult not set new security descriptor DACL: %x\n", status ));
     goto cleanup;
   }

   //
   // We would get and apply the SACL at this point, but NT does not export 
   // the appropriate function, RtlGetSaclSecurityDescriptor :-(
   //

   // 
   // Get and apply the owner
   //
   status = RtlGetOwnerSecurityDescriptor( RelSecurityDescriptor,
					   &Owner,
					   &OwnerDefaulted );
   if( !NT_SUCCESS( status )) {

     DbgPrint(("Secsys: Could not security descriptor owner: %x\n", Owner ));
     goto cleanup;
   }

   status = RtlSetOwnerSecurityDescriptor( absSecurityDescriptor,
					   Owner,
					   OwnerDefaulted );

   if( !NT_SUCCESS( status )) {

     DbgPrint(("Secsys: Could not set owner: %x\n", status ));
     goto cleanup;
   }

   //
   // Get and apply group
   //
   status = RtlGetGroupSecurityDescriptor( RelSecurityDescriptor,
					   &Group,
					   &GroupDefaulted );
   if( !NT_SUCCESS( status )) {

     DbgPrint(("Secsys: Could not security descriptor group: %x\n", Owner ));
     goto cleanup;
   }

   status = RtlSetGroupSecurityDescriptor( absSecurityDescriptor,
					   Group,
					   GroupDefaulted );

   if( !NT_SUCCESS( status )) {

     DbgPrint(("Secsys: Could not set group: %x\n", status ));
     goto cleanup;
   }

   //
   // Finally, make sure that what we made is valid
   //
   if( !RtlValidSecurityDescriptor( absSecurityDescriptor )) {

     DbgPrint(("Secsys: absolute descriptor not valid!\n"));
     status = STATUS_UNSUCCESSFUL;
   }

   //
   // Done! Return.
   //
   
  cleanup:

   if( !NT_SUCCESS( status ) ) {

     ExFreePool( absSecurityDescriptor );
   }
   return status;
}
Example #30
0
VOID
SepInitSystemDacls( VOID )
/*++

Routine Description:

    This function initializes the system's default dacls & security
    descriptors.

Arguments:

    None.

Return Value:

    None.


--*/
{

    NTSTATUS
        Status;

    ULONG
        PublicLength,
        PublicUnrestrictedLength,
        SystemLength,
        PublicOpenLength,
        LocalServiceLength;



    PAGED_CODE();

    //
    // Set up a default ACLs
    //
    //    Public:       WORLD:execute, SYSTEM:all, ADMINS:all
    //    PublicUnrestricted: WORLD:execute, SYSTEM:all, ADMINS:all, Restricted:execute
    //    Public Open:  WORLD:(Read|Write|Execute), ADMINS:(all), SYSTEM:all
    //    System:       SYSTEM:all, ADMINS:(read|execute|read_control)
    //    Unrestricted: WORLD:(all), Restricted:(all)

    SystemLength = (ULONG)sizeof(ACL) +
                   (2*((ULONG)sizeof(ACCESS_ALLOWED_ACE))) +
                   SeLengthSid( SeLocalSystemSid ) +
                   SeLengthSid( SeAliasAdminsSid );

    PublicLength = SystemLength +
                   ((ULONG)sizeof(ACCESS_ALLOWED_ACE)) +
                   SeLengthSid( SeWorldSid );

    PublicUnrestrictedLength = PublicLength +
                   ((ULONG)sizeof(ACCESS_ALLOWED_ACE)) +
                   SeLengthSid( SeRestrictedSid );

    PublicOpenLength = PublicLength;

    LocalServiceLength = (ULONG)sizeof(ACL) +
                         4 * (ULONG)sizeof(ACCESS_ALLOWED_ACE) +
                         SeLengthSid(SeWorldSid) +
                         SeLengthSid(SeLocalSystemSid) +
                         SeLengthSid(SeLocalServiceSid) +
                         SeLengthSid(SeAliasAdminsSid);


    SePublicDefaultDacl = (PACL)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, PublicLength, 'cAeS');
    SePublicDefaultUnrestrictedDacl = (PACL)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, PublicUnrestrictedLength, 'cAeS');
    SePublicOpenDacl = (PACL)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, PublicOpenLength, 'cAeS');
    SePublicOpenUnrestrictedDacl = (PACL)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, PublicUnrestrictedLength, 'cAeS');
    SeSystemDefaultDacl = (PACL)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, SystemLength, 'cAeS');
    SeLocalServicePublicDacl = (PACL)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, LocalServiceLength, 'cAeS');
    ASSERT(SePublicDefaultDacl != NULL);
    ASSERT(SePublicDefaultUnrestrictedDacl != NULL);
    ASSERT(SePublicOpenDacl    != NULL);
    ASSERT(SePublicOpenUnrestrictedDacl    != NULL);
    ASSERT(SeSystemDefaultDacl != NULL);
    ASSERT(SeLocalServicePublicDacl != NULL);



    Status = RtlCreateAcl( SePublicDefaultDacl, PublicLength, ACL_REVISION2);
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlCreateAcl( SePublicDefaultUnrestrictedDacl, PublicUnrestrictedLength, ACL_REVISION2);
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlCreateAcl( SePublicOpenDacl, PublicOpenLength, ACL_REVISION2);
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlCreateAcl( SePublicOpenUnrestrictedDacl, PublicUnrestrictedLength, ACL_REVISION2);
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlCreateAcl( SeSystemDefaultDacl, SystemLength, ACL_REVISION2);
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlCreateAcl( SeLocalServicePublicDacl, LocalServiceLength, ACL_REVISION2);
    ASSERT( NT_SUCCESS(Status) );


    //
    // WORLD access (Public DACLs and OpenUnrestricted only)
    //

    Status = RtlAddAccessAllowedAce (
                 SePublicDefaultDacl,
                 ACL_REVISION2,
                 GENERIC_EXECUTE,
                 SeWorldSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    Status = RtlAddAccessAllowedAce (
                 SePublicDefaultUnrestrictedDacl,
                 ACL_REVISION2,
                 GENERIC_EXECUTE,
                 SeWorldSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    Status = RtlAddAccessAllowedAce (
                 SePublicOpenDacl,
                 ACL_REVISION2,
                 (GENERIC_READ | GENERIC_WRITE  | GENERIC_EXECUTE),
                 SeWorldSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    Status = RtlAddAccessAllowedAce (
                 SePublicOpenUnrestrictedDacl,
                 ACL_REVISION2,
                 (GENERIC_READ | GENERIC_WRITE  | GENERIC_EXECUTE),
                 SeWorldSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    Status = RtlAddAccessAllowedAce (
                 SeLocalServicePublicDacl,
                 ACL_REVISION2,
                 GENERIC_EXECUTE,
                 SeWorldSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    //
    // SYSTEM access  (PublicDefault, PublicOpen, and SystemDefault)
    //


    Status = RtlAddAccessAllowedAce (
                 SePublicDefaultDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeLocalSystemSid
                 );
    ASSERT( NT_SUCCESS(Status) );


    Status = RtlAddAccessAllowedAce (
                 SePublicDefaultUnrestrictedDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeLocalSystemSid
                 );
    ASSERT( NT_SUCCESS(Status) );


    Status = RtlAddAccessAllowedAce (
                 SePublicOpenDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeLocalSystemSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    Status = RtlAddAccessAllowedAce (
                 SePublicOpenUnrestrictedDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeLocalSystemSid
                 );
    ASSERT( NT_SUCCESS(Status) );


    Status = RtlAddAccessAllowedAce (
                 SeSystemDefaultDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeLocalSystemSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    Status = RtlAddAccessAllowedAce (
                 SeLocalServicePublicDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeLocalSystemSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    //
    // ADMINISTRATORS access  (PublicDefault, PublicOpen, and SystemDefault)
    //

    Status = RtlAddAccessAllowedAce (
                 SePublicDefaultDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeAliasAdminsSid
                 );
    ASSERT( NT_SUCCESS(Status) );


    Status = RtlAddAccessAllowedAce (
                 SePublicDefaultUnrestrictedDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeAliasAdminsSid
                 );
    ASSERT( NT_SUCCESS(Status) );


    Status = RtlAddAccessAllowedAce (
                 SePublicOpenDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeAliasAdminsSid
                 );
    ASSERT( NT_SUCCESS(Status) );


    Status = RtlAddAccessAllowedAce (
                 SePublicOpenUnrestrictedDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeAliasAdminsSid
                 );
    ASSERT( NT_SUCCESS(Status) );


    Status = RtlAddAccessAllowedAce (
                 SeSystemDefaultDacl,
                 ACL_REVISION2,
                 GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL,
                 SeAliasAdminsSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    Status = RtlAddAccessAllowedAce (
                 SeLocalServicePublicDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeAliasAdminsSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    //
    // RESTRICTED access  (PublicDefaultUnrestricted and OpenUnrestricted)
    //

    Status = RtlAddAccessAllowedAce (
                 SePublicDefaultUnrestrictedDacl,
                 ACL_REVISION2,
                 GENERIC_EXECUTE,
                 SeRestrictedSid
                 );
    ASSERT( NT_SUCCESS(Status) );

    Status = RtlAddAccessAllowedAce (
                 SePublicOpenUnrestrictedDacl,
                 ACL_REVISION2,
                 GENERIC_EXECUTE | GENERIC_READ,
                 SeRestrictedSid
                 );
    ASSERT( NT_SUCCESS(Status) );


    //
    // Local Service
    //

    Status = RtlAddAccessAllowedAce (
                 SeLocalServicePublicDacl,
                 ACL_REVISION2,
                 GENERIC_ALL,
                 SeLocalServiceSid
                 );
    ASSERT( NT_SUCCESS(Status) );


    //
    // Now initialize security descriptors
    // that export this protection
    //


    SePublicDefaultSd = (PSECURITY_DESCRIPTOR)&SepPublicDefaultSd;
    Status = RtlCreateSecurityDescriptor(
                 SePublicDefaultSd,
                 SECURITY_DESCRIPTOR_REVISION1
                 );
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlSetDaclSecurityDescriptor(
                 SePublicDefaultSd,
                 TRUE,                       // DaclPresent
                 SePublicDefaultDacl,
                 FALSE                       // DaclDefaulted
                 );
    ASSERT( NT_SUCCESS(Status) );


    SePublicDefaultUnrestrictedSd = (PSECURITY_DESCRIPTOR)&SepPublicDefaultUnrestrictedSd;
    Status = RtlCreateSecurityDescriptor(
                 SePublicDefaultUnrestrictedSd,
                 SECURITY_DESCRIPTOR_REVISION1
                 );
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlSetDaclSecurityDescriptor(
                 SePublicDefaultUnrestrictedSd,
                 TRUE,                       // DaclPresent
                 SePublicDefaultUnrestrictedDacl,
                 FALSE                       // DaclDefaulted
                 );
    ASSERT( NT_SUCCESS(Status) );


    SePublicOpenSd = (PSECURITY_DESCRIPTOR)&SepPublicOpenSd;
    Status = RtlCreateSecurityDescriptor(
                 SePublicOpenSd,
                 SECURITY_DESCRIPTOR_REVISION1
                 );
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlSetDaclSecurityDescriptor(
                 SePublicOpenSd,
                 TRUE,                       // DaclPresent
                 SePublicOpenDacl,
                 FALSE                       // DaclDefaulted
                 );
    ASSERT( NT_SUCCESS(Status) );


    SePublicOpenUnrestrictedSd = (PSECURITY_DESCRIPTOR)&SepPublicOpenUnrestrictedSd;
    Status = RtlCreateSecurityDescriptor(
                 SePublicOpenUnrestrictedSd,
                 SECURITY_DESCRIPTOR_REVISION1
                 );
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlSetDaclSecurityDescriptor(
                 SePublicOpenUnrestrictedSd,
                 TRUE,                       // DaclPresent
                 SePublicOpenUnrestrictedDacl,
                 FALSE                       // DaclDefaulted
                 );
    ASSERT( NT_SUCCESS(Status) );


    SeSystemDefaultSd = (PSECURITY_DESCRIPTOR)&SepSystemDefaultSd;
    Status = RtlCreateSecurityDescriptor(
                 SeSystemDefaultSd,
                 SECURITY_DESCRIPTOR_REVISION1
                 );
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlSetDaclSecurityDescriptor(
                 SeSystemDefaultSd,
                 TRUE,                       // DaclPresent
                 SeSystemDefaultDacl,
                 FALSE                       // DaclDefaulted
                 );
    ASSERT( NT_SUCCESS(Status) );

    SeLocalServicePublicSd = (PSECURITY_DESCRIPTOR)&SepLocalServicePublicSd;
    Status = RtlCreateSecurityDescriptor(
                 SeLocalServicePublicSd,
                 SECURITY_DESCRIPTOR_REVISION1
                 );
    ASSERT( NT_SUCCESS(Status) );
    Status = RtlSetDaclSecurityDescriptor(
                 SeLocalServicePublicSd,
                 TRUE,                       // DaclPresent
                 SeLocalServicePublicDacl,
                 FALSE                       // DaclDefaulted
                 );
    ASSERT( NT_SUCCESS(Status) );



    return;

}