Пример #1
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
RtlGetDaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
                             OUT PBOOLEAN DaclPresent,
                             OUT PACL* Dacl,
                             OUT PBOOLEAN DaclDefaulted)
{
    PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
    PAGED_CODE_RTL();

    /* Fail on invalid revisions */
    if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;

    /* Is there a DACL? */
    *DaclPresent = (Sd->Control & SE_DACL_PRESENT) == SE_DACL_PRESENT;
    if (*DaclPresent)
    {
        /* Yes, return it, and check if defaulted */
        *Dacl = SepGetDaclFromDescriptor(Sd);
        *DaclDefaulted = (Sd->Control & SE_DACL_DEFAULTED) == SE_DACL_DEFAULTED;
    }

    /* All good */
    return STATUS_SUCCESS;
}
Пример #2
0
/*
 * @implemented
 */
ULONG
NTAPI
RtlLengthSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
    PISECURITY_DESCRIPTOR Sd;
    PSID Owner, Group;
    PACL Sacl, Dacl;
    ULONG Length;
    PAGED_CODE_RTL();

    /* Start with the initial length of the SD itself */
    Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
    if (Sd->Control & SE_SELF_RELATIVE)
    {
        Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
    }
    else
    {
        Length = sizeof(SECURITY_DESCRIPTOR);
    }

    /* Add the length of the individual subcomponents */
    Owner = SepGetOwnerFromDescriptor(Sd);
    if (Owner) Length += ROUND_UP(RtlLengthSid(Owner), sizeof(ULONG));
    Group = SepGetGroupFromDescriptor(Sd);
    if (Group) Length += ROUND_UP(RtlLengthSid(Group), sizeof(ULONG));
    Dacl = SepGetDaclFromDescriptor(Sd);
    if (Dacl) Length += ROUND_UP(Dacl->AclSize, sizeof(ULONG));
    Sacl = SepGetSaclFromDescriptor(Sd);
    if (Sacl) Length += ROUND_UP(Sacl->AclSize, sizeof(ULONG));

    /* Return the final length */
    return Length;
}
Пример #3
0
/*
 * @implemented
 */
BOOLEAN
NTAPI
RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
    PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
    PSID Owner, Group;
    PACL Sacl, Dacl;
    PAGED_CODE_RTL();

    _SEH2_TRY
    {
        /* Fail on bad revisions */
        if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return FALSE;

        /* Owner SID must be valid if present */
        Owner = SepGetOwnerFromDescriptor(Sd);
        if ((Owner) && (!RtlValidSid(Owner))) return FALSE;

        /* Group SID must be valid if present */
        Group = SepGetGroupFromDescriptor(Sd);
        if ((Owner) && (!RtlValidSid(Group))) return FALSE;

        /* DACL must be valid if present */
        Dacl = SepGetDaclFromDescriptor(Sd);
        if ((Dacl) && (!RtlValidAcl(Dacl))) return FALSE;

        /* SACL must be valid if present */
        Sacl = SepGetSaclFromDescriptor(Sd);
        if ((Sacl) && (!RtlValidAcl(Sacl))) return FALSE;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        /* Access fault, bail out */
        return FALSE;
    }
    _SEH2_END;

    /* All good */
    return TRUE;
}
Пример #4
0
VOID
NTAPI
RtlpQuerySecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptor,
                            OUT PSID *Owner,
                            OUT PULONG OwnerSize,
                            OUT PSID *PrimaryGroup,
                            OUT PULONG PrimaryGroupSize,
                            OUT PACL *Dacl,
                            OUT PULONG DaclSize,
                            OUT PACL *Sacl,
                            OUT PULONG SaclSize)
{
    PAGED_CODE_RTL();

    /* Get the owner */
    *Owner = SepGetOwnerFromDescriptor(SecurityDescriptor);
    if (*Owner)
    {
        /* There's an owner, so align the size */
        *OwnerSize = ROUND_UP(RtlLengthSid(*Owner), sizeof(ULONG));
    }
    else
    {
        /* No owner, no size */
        *OwnerSize = 0;
    }

    /* Get the group */
    *PrimaryGroup = SepGetGroupFromDescriptor(SecurityDescriptor);
    if (*PrimaryGroup)
    {
        /* There's a group, so align the size */
        *PrimaryGroupSize = ROUND_UP(RtlLengthSid(*PrimaryGroup), sizeof(ULONG));
    }
    else
    {
        /* No group, no size */
        *PrimaryGroupSize = 0;
    }

    /* Get the DACL */
    *Dacl = SepGetDaclFromDescriptor(SecurityDescriptor);
    if (*Dacl)
    {
        /* There's a DACL, align the size */
        *DaclSize = ROUND_UP((*Dacl)->AclSize, sizeof(ULONG));
    }
    else
    {
        /* No DACL, no size */
        *DaclSize = 0;
    }

    /* Get the SACL */
    *Sacl = SepGetSaclFromDescriptor(SecurityDescriptor);
    if (*Sacl)
    {
        /* There's a SACL, align the size */
        *SaclSize = ROUND_UP((*Sacl)->AclSize, sizeof(ULONG));
    }
    else
    {
        /* No SACL, no size */
        *SaclSize = 0;
    }
}
Пример #5
0
/*
 * @implemented
 */
BOOLEAN
NTAPI
SeFastTraverseCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
                    IN PACCESS_STATE AccessState,
                    IN ACCESS_MASK DesiredAccess,
                    IN KPROCESSOR_MODE AccessMode)
{
    PACL Dacl;
    ULONG AceIndex;
    PKNOWN_ACE Ace;

    PAGED_CODE();

    NT_ASSERT(AccessMode != KernelMode);

    if (SecurityDescriptor == NULL)
        return FALSE;

    /* Get DACL */
    Dacl = SepGetDaclFromDescriptor(SecurityDescriptor);
    /* If no DACL, grant access */
    if (Dacl == NULL)
        return TRUE;

    /* No ACE -> Deny */
    if (!Dacl->AceCount)
        return FALSE;

    /* Can't perform the check on restricted token */
    if (AccessState->Flags & TOKEN_IS_RESTRICTED)
        return FALSE;

    /* Browse the ACEs */
    for (AceIndex = 0, Ace = (PKNOWN_ACE)((ULONG_PTR)Dacl + sizeof(ACL));
         AceIndex < Dacl->AceCount;
         AceIndex++, Ace = (PKNOWN_ACE)((ULONG_PTR)Ace + Ace->Header.AceSize))
    {
        if (Ace->Header.AceFlags & INHERIT_ONLY_ACE)
            continue;

        /* If access-allowed ACE */
        if (Ace->Header.AceType & ACCESS_ALLOWED_ACE_TYPE)
        {
            /* Check if all accesses are granted */
            if (!(Ace->Mask & DesiredAccess))
                continue;

            /* Check SID and grant access if matching */
            if (RtlEqualSid(SeWorldSid, &(Ace->SidStart)))
                return TRUE;
        }
        /* If access-denied ACE */
        else if (Ace->Header.AceType & ACCESS_DENIED_ACE_TYPE)
        {
            /* Here, only check if it denies all the access wanted and deny if so */
            if (Ace->Mask & DesiredAccess)
                return FALSE;
        }
    }

    /* Faulty, deny */
    return FALSE;
}