static
VOID
LwpsLegacyFreeSecurityDescriptor(
    IN OUT PSECURITY_DESCRIPTOR_ABSOLUTE *ppSecurityDescriptor
    )
{
    if (*ppSecurityDescriptor)
    {
        PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = *ppSecurityDescriptor;
        PSID pOwner = NULL;
        PSID pGroup = NULL;
        PACL pDacl = NULL;
        PACL pSacl = NULL;
        BOOLEAN bDefaulted = FALSE;
        BOOLEAN bPresent = FALSE;

        RtlGetOwnerSecurityDescriptor(pSecDesc, &pOwner, &bDefaulted);
        RtlGetGroupSecurityDescriptor(pSecDesc, &pGroup, &bDefaulted);
        RtlGetDaclSecurityDescriptor(pSecDesc, &bPresent, &pDacl, &bDefaulted);
        RtlGetSaclSecurityDescriptor(pSecDesc, &bPresent, &pSacl, &bDefaulted);

        LW_RTL_FREE(&pSecDesc);
        LW_RTL_FREE(&pOwner);
        LW_RTL_FREE(&pGroup);
        LW_RTL_FREE(&pDacl);
        LW_RTL_FREE(&pSacl);

        *ppSecurityDescriptor = NULL;
    }
}
예제 #2
0
NTSTATUS PhSetSeObjectSecurity(
    _In_ HANDLE Handle,
    _In_ ULONG ObjectType,
    _In_ SECURITY_INFORMATION SecurityInformation,
    _In_ PSECURITY_DESCRIPTOR SecurityDescriptor
)
{
    ULONG win32Result;
    SECURITY_INFORMATION securityInformation = 0;
    BOOLEAN present;
    BOOLEAN defaulted;
    PSID owner = NULL;
    PSID group = NULL;
    PACL dacl = NULL;
    PACL sacl = NULL;

    if (SecurityInformation & OWNER_SECURITY_INFORMATION)
    {
        if (NT_SUCCESS(RtlGetOwnerSecurityDescriptor(SecurityDescriptor, &owner, &defaulted)))
            securityInformation |= OWNER_SECURITY_INFORMATION;
    }

    if (SecurityInformation & GROUP_SECURITY_INFORMATION)
    {
        if (NT_SUCCESS(RtlGetGroupSecurityDescriptor(SecurityDescriptor, &group, &defaulted)))
            securityInformation |= GROUP_SECURITY_INFORMATION;
    }

    if (SecurityInformation & DACL_SECURITY_INFORMATION)
    {
        if (NT_SUCCESS(RtlGetDaclSecurityDescriptor(SecurityDescriptor, &present, &dacl, &defaulted)) && present)
            securityInformation |= DACL_SECURITY_INFORMATION;
    }

    if (SecurityInformation & SACL_SECURITY_INFORMATION)
    {
        if (NT_SUCCESS(RtlGetSaclSecurityDescriptor(SecurityDescriptor, &present, &sacl, &defaulted)) && present)
            securityInformation |= SACL_SECURITY_INFORMATION;
    }

    win32Result = SetSecurityInfo(
                      Handle,
                      ObjectType,
                      SecurityInformation,
                      owner,
                      group,
                      dacl,
                      sacl
                  );

    if (win32Result != ERROR_SUCCESS)
        return NTSTATUS_FROM_WIN32(win32Result);

    return STATUS_SUCCESS;
}
예제 #3
0
VOID
EVTFreeSecurityDescriptor(
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc
    )
{
    PSID pOwnerSid = NULL;
    BOOLEAN bOwnerDefaulted = FALSE;
    PSID pPrimaryGroupSid = NULL;
    BOOLEAN bPrimaryGroupDefaulted = FALSE;
    PACL pDacl = NULL;
    BOOLEAN bDaclPresent = FALSE;
    BOOLEAN bDaclDefaulted = FALSE;
    PACL pSacl = NULL;
    BOOLEAN bSaclPresent = FALSE;
    BOOLEAN bSaclDefaulted = FALSE;

    if (pSecDesc)
    {
        RtlGetOwnerSecurityDescriptor(pSecDesc,
                                                 &pOwnerSid,
                                                 &bOwnerDefaulted);
        LW_SAFE_FREE_MEMORY(pOwnerSid);

        RtlGetGroupSecurityDescriptor(pSecDesc,
                                                 &pPrimaryGroupSid,
                                                 &bPrimaryGroupDefaulted);
        LW_SAFE_FREE_MEMORY(pPrimaryGroupSid);

        RtlGetDaclSecurityDescriptor(pSecDesc,
                                                &bDaclPresent,
                                                &pDacl,
                                                &bDaclDefaulted);
        LW_SAFE_FREE_MEMORY(pDacl);

        RtlGetSaclSecurityDescriptor(pSecDesc,
                                                &bSaclPresent,
                                                &pSacl,
                                                &bSaclDefaulted);
        LW_SAFE_FREE_MEMORY(pSacl);

        LW_SAFE_FREE_MEMORY(pSecDesc);
    }
}
예제 #4
0
VOID
EventLogShutdown(
    VOID
    )
{
    EventLogRPCShutdown();

    EventLogServiceShutdown();

    EventLogDbShutdown();

#ifndef _WIN32
    if (gEventLogServerGlobals.gSecurityDescriptor)
    {
        PSID pOwnerSID = NULL;
        BOOLEAN bDefaulted = FALSE;
        BOOLEAN bDaclPresent = FALSE;
        PACL pDacl = NULL;

        if (STATUS_SUCCESS == RtlGetOwnerSecurityDescriptor(
                                    gEventLogServerGlobals.gSecurityDescriptor,
                                    &pOwnerSID,
                                    &bDefaulted))
        {
            RTL_FREE(&pOwnerSID);
        }

        if (STATUS_SUCCESS == RtlGetDaclSecurityDescriptor(
                                    gEventLogServerGlobals.gSecurityDescriptor,
                                    &bDaclPresent,
                                    &pDacl,
                                    &bDefaulted) && bDaclPresent && pDacl)
        {
            EventLogFreeMemory(pDacl);
        }

        EventLogFreeMemory(gEventLogServerGlobals.gSecurityDescriptor);
    }
#endif
}
예제 #5
0
static
VOID
SrvShareFreeAbsoluteSecurityDescriptor(
    IN OUT PSECURITY_DESCRIPTOR_ABSOLUTE *ppSecDesc
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSID pOwner = NULL;
    PSID pGroup = NULL;
    PACL pDacl = NULL;
    PACL pSacl = NULL;
    BOOLEAN bDefaulted = FALSE;
    BOOLEAN bPresent = FALSE;
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;

    if ((ppSecDesc == NULL) || (*ppSecDesc == NULL))
    {
        return;
    }

    pSecDesc = *ppSecDesc;

    ntStatus = RtlGetOwnerSecurityDescriptor(pSecDesc, &pOwner, &bDefaulted);
    ntStatus = RtlGetGroupSecurityDescriptor(pSecDesc, &pGroup, &bDefaulted);

    ntStatus = RtlGetDaclSecurityDescriptor(pSecDesc, &bPresent, &pDacl, &bDefaulted);
    ntStatus = RtlGetSaclSecurityDescriptor(pSecDesc, &bPresent, &pSacl, &bDefaulted);
    ntStatus = ntStatus;

    RTL_FREE(&pSecDesc);
    RTL_FREE(&pOwner);
    RTL_FREE(&pGroup);
    RTL_FREE(&pDacl);
    RTL_FREE(&pSacl);

    *ppSecDesc = NULL;

    return;
}
예제 #6
0
파일: sec.c 프로젝트: GYGit/reactos
/*
 * @implemented
 */
BOOL
WINAPI
GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor,
                           PSID *pOwner,
                           LPBOOL lpbOwnerDefaulted)
{
    BOOLEAN OwnerDefaulted;
    NTSTATUS Status;

    Status = RtlGetOwnerSecurityDescriptor(pSecurityDescriptor,
                                           pOwner,
                                           &OwnerDefaulted);
    *lpbOwnerDefaulted = (BOOL)OwnerDefaulted;

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

    return TRUE;
}
예제 #7
0
NTSTATUS
SrvShareSetSecurity(
    IN  PSRV_SHARE_INFO pShareInfo,
    IN  PSECURITY_DESCRIPTOR_RELATIVE pIncRelSecDesc,
    IN  ULONG ulIncRelSecDescLen
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSECURITY_DESCRIPTOR_ABSOLUTE pIncAbsSecDesc = NULL;
    PSECURITY_DESCRIPTOR_ABSOLUTE pFinalAbsSecDesc = NULL;
    PSECURITY_DESCRIPTOR_RELATIVE pFinalRelSecDesc = NULL;
    ULONG ulFinalRelSecDescLen = 0;
    SECURITY_INFORMATION secInfo = 0;
    PSID pOwner = NULL;
    PSID pGroup = NULL;
    PACL pDacl = NULL;
    PACL pSacl = NULL;
    BOOLEAN bDefaulted = FALSE;
    BOOLEAN bPresent = FALSE;
    GENERIC_MAPPING GenericMap = {
        .GenericRead    = FILE_GENERIC_READ,
        .GenericWrite   = FILE_GENERIC_WRITE,
        .GenericExecute = FILE_GENERIC_EXECUTE,
        .GenericAll     = FILE_ALL_ACCESS };

    /* Sanity checks */

    if ((pIncRelSecDesc == NULL) || (ulIncRelSecDescLen == 0))
    {
        ntStatus = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (pShareInfo->ulSecDescLen == 0)
    {
        ntStatus = SrvShareSetDefaultSecurity(pShareInfo);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    /* Make the Absolute version of thr incoming SD and
       get the SecurityInformation */

    ntStatus = SrvShareCreateAbsoluteSecDescFromRel(
                    &pIncAbsSecDesc,
                    pIncRelSecDesc) ;
    BAIL_ON_NT_STATUS(ntStatus);

    /* Don't bail on these.  We'll be checking the pointer */

    ntStatus = RtlGetOwnerSecurityDescriptor(
                   pIncAbsSecDesc,
                   &pOwner,
                   &bDefaulted);
    secInfo |= pOwner ? OWNER_SECURITY_INFORMATION : 0;

    ntStatus = RtlGetGroupSecurityDescriptor(
                   pIncAbsSecDesc,
                   &pGroup,
                   &bDefaulted);
    secInfo |= pGroup ? GROUP_SECURITY_INFORMATION : 0;

    ntStatus = RtlGetDaclSecurityDescriptor(
                   pIncAbsSecDesc,
                   &bPresent,
                   &pDacl,
                   &bDefaulted);
    secInfo |= pDacl ? DACL_SECURITY_INFORMATION : 0;

    ntStatus = RtlGetSaclSecurityDescriptor(
                   pIncAbsSecDesc,
                   &bPresent,
                   &pSacl,
                   &bDefaulted);
    secInfo |= pSacl ? SACL_SECURITY_INFORMATION  : 0;

    /* Assume the new length is not longer than the combined length
       of both the current and incoming relative SecDesc buffers */

    ulFinalRelSecDescLen = ulIncRelSecDescLen + pShareInfo->ulSecDescLen;

    ntStatus = SrvAllocateMemory(
                   ulFinalRelSecDescLen,
                   (PVOID*)&pFinalRelSecDesc);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetSecurityDescriptorInfo(
                   secInfo,
                   pIncRelSecDesc,
                   pShareInfo->pSecDesc,
                   pFinalRelSecDesc,
                   &ulFinalRelSecDescLen,
                   &GenericMap);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvShareCreateAbsoluteSecDescFromRel(
                    &pFinalAbsSecDesc,
                    pFinalRelSecDesc) ;
    BAIL_ON_NT_STATUS(ntStatus);

    /* Free the old SecDesc and save the new one */

    SrvShareFreeSecurity(pShareInfo);

    pShareInfo->pSecDesc = pFinalRelSecDesc;
    pShareInfo->ulSecDescLen = ulFinalRelSecDescLen;
    pShareInfo->pAbsSecDesc = pFinalAbsSecDesc;

    ntStatus = STATUS_SUCCESS;

cleanup:
    if (pIncAbsSecDesc)
    {
        SrvShareFreeAbsoluteSecurityDescriptor(&pIncAbsSecDesc);
    }

    return ntStatus;

error:
    if (pFinalRelSecDesc)
    {
        SrvFreeMemory(pFinalRelSecDesc);
    }

    if (pFinalAbsSecDesc)
    {
        SrvShareFreeAbsoluteSecurityDescriptor(&pFinalAbsSecDesc);
    }

    goto cleanup;
}
예제 #8
0
NTSTATUS
PvfsAccessCheckFileEnumerate(
    PPVFS_CCB pCcb,
    PCSTR pszRelativeFilename
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PACCESS_TOKEN pToken = pCcb->pUserToken;
    PSTR pszFilename = NULL;
    ACCESS_MASK AccessMask = 0;
    ACCESS_MASK GrantedAccess = 0;
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
    BYTE pRelativeSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE];
    ULONG ulRelativeSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE;
    BOOLEAN bGranted = FALSE;
    SECURITY_INFORMATION SecInfo = (OWNER_SECURITY_INFORMATION |
                                    GROUP_SECURITY_INFORMATION |
                                    DACL_SECURITY_INFORMATION  |
                                    SACL_SECURITY_INFORMATION);
    ACCESS_MASK Desired = (FILE_READ_ATTRIBUTES|
                           FILE_READ_EA|
                           FILE_READ_DATA|
                           READ_CONTROL);
    PSID pOwner = NULL;
    BOOLEAN bOwnerDefaulted = FALSE;

    /* Create the absolute path */

    ntError = LwRtlCStringAllocatePrintf(
                  &pszFilename,
                  "%s/%s",
                  pCcb->pScb->pOwnerFcb->pszFilename,
                  pszRelativeFilename);
    BAIL_ON_NT_STATUS(ntError);

    /* Check the file object itself */

    ntError = PvfsGetSecurityDescriptorFilename(
                  pszFilename,
                  SecInfo,
                  (PSECURITY_DESCRIPTOR_RELATIVE)((PVOID)pRelativeSecDescBuffer),
                  &ulRelativeSecDescLength);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsSecurityAclSelfRelativeToAbsoluteSD(
                  &pSecDesc,
                  (PSECURITY_DESCRIPTOR_RELATIVE)((PVOID)pRelativeSecDescBuffer));
    BAIL_ON_NT_STATUS(ntError);

    // Tests against NTFS/Win2003R2 show that the file/directory object
    // owner is always granted FILE_READ_ATTRIBUTE

    ntError = RtlGetOwnerSecurityDescriptor(
                  pSecDesc,
                  &pOwner,
                  &bOwnerDefaulted);
    BAIL_ON_NT_STATUS(ntError);

    if (RtlIsSidMemberOfToken(pToken, pOwner))
    {
        ClearFlag(Desired, FILE_READ_ATTRIBUTES);
        SetFlag(GrantedAccess, FILE_READ_ATTRIBUTES);
    }

    /* Now check access */

    bGranted = RtlAccessCheck(
                   pSecDesc,
                   pToken,
                   Desired,
                   GrantedAccess,
                   &gPvfsDriverState.GenericSecurityMap,
                   &AccessMask,
                   &ntError);
    if (!bGranted)
    {
        ntError = STATUS_ACCESS_DENIED;
    }
    BAIL_ON_NT_STATUS(ntError);

cleanup:
    if (pszFilename)
    {
        LwRtlCStringFree(&pszFilename);
    }

    if (pSecDesc)
    {
        PvfsFreeAbsoluteSecurityDescriptor(&pSecDesc);
    }

    return ntError;

error:
    goto cleanup;
}
예제 #9
0
NTSTATUS
PvfsAccessCheckFile(
    PACCESS_TOKEN pToken,
    PPVFS_FILE_NAME FileName,
    ACCESS_MASK Desired,
    ACCESS_MASK *pGranted
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    ACCESS_MASK AccessMask = 0;
    ACCESS_MASK GrantedAccess = 0;
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
    BYTE pRelativeSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE];
    ULONG ulRelativeSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE;
    PSECURITY_DESCRIPTOR_ABSOLUTE pParentSecDesc = NULL;
    BYTE pParentRelSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE];
    ULONG ulParentRelSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE;
    BOOLEAN bGranted = FALSE;
    SECURITY_INFORMATION SecInfo = (OWNER_SECURITY_INFORMATION |
                                    GROUP_SECURITY_INFORMATION |
                                    DACL_SECURITY_INFORMATION  |
                                    SACL_SECURITY_INFORMATION);
    PSID pOwner = NULL;
    BOOLEAN bOwnerDefaulted = FALSE;
    BOOLEAN bWantsDelete = FALSE;
    BOOLEAN bWantsMaximumAccess = FALSE;
    PPVFS_FILE_NAME parentDirectoryName = NULL;
    PPVFS_FILE_NAME relativeFileName = NULL;

    BAIL_ON_INVALID_PTR(pToken, ntError);
    BAIL_ON_INVALID_PTR(pGranted, ntError);

    // Check the file object itself

    ntError = PvfsGetSecurityDescriptorFilename(
                  PvfsGetCStringBaseFileName(FileName),
                  SecInfo,
                  (PSECURITY_DESCRIPTOR_RELATIVE)((PVOID)pRelativeSecDescBuffer),
                  &ulRelativeSecDescLength);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsSecurityAclSelfRelativeToAbsoluteSD(
                  &pSecDesc,
                  (PSECURITY_DESCRIPTOR_RELATIVE)((PVOID)pRelativeSecDescBuffer));
    BAIL_ON_NT_STATUS(ntError);

    // Tests against NTFS/Win2003R2 show that the file/directory object
    // owner is always granted FILE_READ_ATTRIBUTE

    ntError = RtlGetOwnerSecurityDescriptor(
                  pSecDesc,
                  &pOwner,
                  &bOwnerDefaulted);
    BAIL_ON_NT_STATUS(ntError);

    if (RtlIsSidMemberOfToken(pToken, pOwner))
    {
        ClearFlag(Desired, FILE_READ_ATTRIBUTES);
        SetFlag(GrantedAccess, FILE_READ_ATTRIBUTES);
    }

    // Check for access rights.  We'll deal with DELETE separately since that
    // could be granted by the parent directory security descriptor

    if (Desired & DELETE)
    {
        bWantsDelete = TRUE;
        ClearFlag(Desired, DELETE);
    }

    if (Desired & MAXIMUM_ALLOWED)
    {
        bWantsMaximumAccess = TRUE;
    }

    bGranted = RtlAccessCheck(
                   pSecDesc,
                   pToken,
                   Desired,
                   GrantedAccess,
                   &gPvfsDriverState.GenericSecurityMap,
                   &AccessMask,
                   &ntError);
    if (!bGranted)
    {
        BAIL_ON_NT_STATUS(ntError);
    }

    GrantedAccess = AccessMask;

    // See if the file object security descriptor grants DELETE
    // Only continue when checking for MAXIMUM_ALLOWED if we haven't been
    // granted DELETE already

    if (bWantsDelete ||
        (bWantsMaximumAccess && !(GrantedAccess & DELETE)))
    {
        AccessMask = 0;

        bGranted = RtlAccessCheck(
                   pSecDesc,
                   pToken,
                   DELETE,
                   GrantedAccess,
                   &gPvfsDriverState.GenericSecurityMap,
                   &AccessMask,
                   &ntError);
        if (!bGranted)
        {
            ntError = PvfsSplitFileNamePath(
                          &parentDirectoryName,
                          &relativeFileName,
                          FileName);
            BAIL_ON_NT_STATUS(ntError);

            ntError = PvfsGetSecurityDescriptorFilename(
                          PvfsGetCStringBaseFileName(parentDirectoryName),
                          SecInfo,
                          (PSECURITY_DESCRIPTOR_RELATIVE)((PVOID)pParentRelSecDescBuffer),
                          &ulParentRelSecDescLength);
            BAIL_ON_NT_STATUS(ntError);

            ntError = PvfsSecurityAclSelfRelativeToAbsoluteSD(
                          &pParentSecDesc,
                          (PSECURITY_DESCRIPTOR_RELATIVE)((PVOID)pParentRelSecDescBuffer));
            BAIL_ON_NT_STATUS(ntError);

            AccessMask = 0;
            bGranted = RtlAccessCheck(
                           pParentSecDesc,
                           pToken,
                           FILE_DELETE_CHILD,
                           0,
                           &gPvfsDriverState.GenericSecurityMap,
                           &AccessMask,
                           &ntError);

            // This is a hard failure unless we are just trying to determine
            // what the maximum allowed access would be

            if (!bGranted && !bWantsMaximumAccess)
            {
                BAIL_ON_NT_STATUS(ntError);
            }

            AccessMask = DELETE;
        }

        // Combine directory and file object granted permissions

        AccessMask |= GrantedAccess;
    }

    *pGranted = AccessMask;
    ntError = STATUS_SUCCESS;

error:
    if (parentDirectoryName)
    {
        PvfsFreeFileName(relativeFileName);
    }
    if (relativeFileName)
    {
        PvfsFreeFileName(parentDirectoryName);
    }


    if (pParentSecDesc)
    {
        PvfsFreeAbsoluteSecurityDescriptor(&pParentSecDesc);
    }

    if (pSecDesc)
    {
        PvfsFreeAbsoluteSecurityDescriptor(&pSecDesc);
    }

    return ntError;
}
예제 #10
0
/******************************************************************************
 * GetSecurityDescriptorOwner [ADVAPI32.@]
 *
 * PARAMS
 *   pOwner            []
 *   lpbOwnerDefaulted []
 */
BOOL WINAPI
GetSecurityDescriptorOwner( SECURITY_DESCRIPTOR *pDescr, PSID *pOwner,
                            LPBOOL lpbOwnerDefaulted )
{
    CallWin32ToNt (RtlGetOwnerSecurityDescriptor( pDescr, pOwner, (PBOOLEAN)lpbOwnerDefaulted ));
}
예제 #11
0
VOID
LocalDirFreeSecurityDescriptor(
    PSECURITY_DESCRIPTOR_ABSOLUTE *ppSecDesc
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
    PSID pOwnerSid = NULL;
    BOOLEAN bOwnerDefaulted = FALSE;
    PSID pPrimaryGroupSid = NULL;
    BOOLEAN bPrimaryGroupDefaulted = FALSE;
    PACL pDacl = NULL;
    BOOLEAN bDaclPresent = FALSE;
    BOOLEAN bDaclDefaulted = FALSE;
    PACL pSacl = NULL;
    BOOLEAN bSaclPresent = FALSE;
    BOOLEAN bSaclDefaulted = FALSE;

    if (ppSecDesc == NULL ||
        *ppSecDesc == NULL)
    {
        return;
    }

    pSecDesc = *ppSecDesc;

    ntStatus = RtlGetOwnerSecurityDescriptor(pSecDesc,
                                             &pOwnerSid,
                                             &bOwnerDefaulted);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlGetGroupSecurityDescriptor(pSecDesc,
                                             &pPrimaryGroupSid,
                                             &bPrimaryGroupDefaulted);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlGetDaclSecurityDescriptor(pSecDesc,
                                            &bDaclPresent,
                                            &pDacl,
                                            &bDaclDefaulted);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlGetSaclSecurityDescriptor(pSecDesc,
                                            &bSaclPresent,
                                            &pSacl,
                                            &bSaclDefaulted);
    BAIL_ON_NT_STATUS(ntStatus);

error:
    LW_SAFE_FREE_MEMORY(pOwnerSid);
    LW_SAFE_FREE_MEMORY(pPrimaryGroupSid);

    if (bDaclPresent)
    {
        LW_SAFE_FREE_MEMORY(pDacl);
    }

    if (bSaclPresent)
    {
        LW_SAFE_FREE_MEMORY(pSacl);
    }

    LW_SAFE_FREE_MEMORY(pSecDesc);
    *ppSecDesc = NULL;
}
예제 #12
0
/* creates a struct security_descriptor and contained information in one contiguous piece of memory */
NTSTATUS NTDLL_create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd,
                                data_size_t *server_sd_len)
{
    unsigned int len;
    PSID owner, group;
    ACL *dacl, *sacl;
    BOOLEAN owner_present, group_present, dacl_present, sacl_present;
    BOOLEAN defaulted;
    NTSTATUS status;
    unsigned char *ptr;

    if (!nt_sd)
    {
        *server_sd = NULL;
        *server_sd_len = 0;
        return STATUS_SUCCESS;
    }

    len = sizeof(struct security_descriptor);

    status = RtlGetOwnerSecurityDescriptor(nt_sd, &owner, &owner_present);
    if (status != STATUS_SUCCESS) return status;
    status = RtlGetGroupSecurityDescriptor(nt_sd, &group, &group_present);
    if (status != STATUS_SUCCESS) return status;
    status = RtlGetSaclSecurityDescriptor(nt_sd, &sacl_present, &sacl, &defaulted);
    if (status != STATUS_SUCCESS) return status;
    status = RtlGetDaclSecurityDescriptor(nt_sd, &dacl_present, &dacl, &defaulted);
    if (status != STATUS_SUCCESS) return status;

    if (owner_present)
        len += RtlLengthSid(owner);
    if (group_present)
        len += RtlLengthSid(group);
    if (sacl_present && sacl)
        len += sacl->AclSize;
    if (dacl_present && dacl)
        len += dacl->AclSize;

    /* fix alignment for the Unicode name that follows the structure */
    len = (len + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1);
    *server_sd = RtlAllocateHeap(GetProcessHeap(), 0, len);
    if (!*server_sd) return STATUS_NO_MEMORY;

    (*server_sd)->control = ((SECURITY_DESCRIPTOR *)nt_sd)->Control & ~SE_SELF_RELATIVE;
    (*server_sd)->owner_len = owner_present ? RtlLengthSid(owner) : 0;
    (*server_sd)->group_len = group_present ? RtlLengthSid(group) : 0;
    (*server_sd)->sacl_len = (sacl_present && sacl) ? sacl->AclSize : 0;
    (*server_sd)->dacl_len = (dacl_present && dacl) ? dacl->AclSize : 0;

    ptr = (unsigned char *)(*server_sd + 1);
    memcpy(ptr, owner, (*server_sd)->owner_len);
    ptr += (*server_sd)->owner_len;
    memcpy(ptr, group, (*server_sd)->group_len);
    ptr += (*server_sd)->group_len;
    memcpy(ptr, sacl, (*server_sd)->sacl_len);
    ptr += (*server_sd)->sacl_len;
    memcpy(ptr, dacl, (*server_sd)->dacl_len);

    *server_sd_len = len;

    return STATUS_SUCCESS;
}
예제 #13
0
NTSTATUS
PvfsSetSecurityDescriptorFile(
    IN PPVFS_CCB pCcb,
    IN SECURITY_INFORMATION SecInfo,
    IN PSECURITY_DESCRIPTOR_RELATIVE pSecDesc,
    IN ULONG SecDescLength
    )
{
    NTSTATUS ntError = STATUS_ACCESS_DENIED;
    PSECURITY_DESCRIPTOR_RELATIVE pFinalSecDesc = NULL;
    ULONG ulFinalSecDescLength = 0;
    SECURITY_INFORMATION SecInfoAll = (OWNER_SECURITY_INFORMATION |
                                       GROUP_SECURITY_INFORMATION |
                                       DACL_SECURITY_INFORMATION |
                                       SACL_SECURITY_INFORMATION);
    BYTE pCurrentSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE];
    ULONG ulCurrentSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE;
    BYTE pNewSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE];
    ULONG ulNewSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE;
    PSECURITY_DESCRIPTOR_ABSOLUTE pIncAbsSecDesc = NULL;
    union {
        TOKEN_OWNER TokenOwnerInfo;
        BYTE Buffer[SID_MAX_SIZE];
    } TokenOwnerBuffer;
    PTOKEN_OWNER pTokenOwnerInformation = (PTOKEN_OWNER)&TokenOwnerBuffer;
    ULONG ulTokenOwnerLength = 0;
    union {
        SID Sid;
        BYTE Buffer[SID_MAX_SIZE];
    } LocalSystemSidBuffer;
    PSID pLocalSystemSid = (PSID)&LocalSystemSidBuffer;
    ULONG ulLocalSystemSidLength = sizeof(LocalSystemSidBuffer);

    memset(pCurrentSecDescBuffer, 0, SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE);
    memset(pNewSecDescBuffer, 0, SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE);
    memset(TokenOwnerBuffer.Buffer, 0, SID_MAX_SIZE);

    /* Sanity checks */

    if (SecInfo == 0)
    {
        ntError = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntError);
    }

    /* If the new Security Descriptor contains owner or group SID
       information, berify that the user's ACCESS_TOKEN contains the
       SID as a member */

    if (SecInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
    {
        PSID pOwner = NULL;
        PSID pGroup = NULL;
        BOOLEAN bDefaulted = FALSE;

        ntError = PvfsSecurityAclSelfRelativeToAbsoluteSD(
                      &pIncAbsSecDesc,
                      pSecDesc);
        BAIL_ON_NT_STATUS(ntError);

        ntError = RtlQueryAccessTokenInformation(
                      pCcb->pUserToken,
                      TokenOwner,
                      (PVOID)pTokenOwnerInformation,
                      sizeof(TokenOwnerBuffer),
                      &ulTokenOwnerLength);
        BAIL_ON_NT_STATUS(ntError);

        ntError = RtlCreateWellKnownSid(
                      WinLocalSystemSid,
                      NULL,
                      pLocalSystemSid,
                      &ulLocalSystemSidLength);
        BAIL_ON_NT_STATUS(ntError);

        if (SecInfo & OWNER_SECURITY_INFORMATION)
        {
            ntError = RtlGetOwnerSecurityDescriptor(
                          pIncAbsSecDesc,
                          &pOwner,
                          &bDefaulted);
            BAIL_ON_NT_STATUS(ntError);

            if (!RtlIsSidMemberOfToken(pCcb->pUserToken, pOwner) &&
                !RtlEqualSid(pLocalSystemSid, pTokenOwnerInformation->Owner))
            {
                ntError = STATUS_ACCESS_DENIED;
                BAIL_ON_NT_STATUS(ntError);
            }
        }

        if (SecInfo & GROUP_SECURITY_INFORMATION)
        {
            ntError = RtlGetGroupSecurityDescriptor(
                          pIncAbsSecDesc,
                          &pGroup,
                          &bDefaulted);
            BAIL_ON_NT_STATUS(ntError);

            if (!RtlIsSidMemberOfToken(pCcb->pUserToken, pGroup) &&
                !RtlEqualSid(pLocalSystemSid, pTokenOwnerInformation->Owner))
            {
                ntError = STATUS_ACCESS_DENIED;
                BAIL_ON_NT_STATUS(ntError);
            }
        }
    }


    if (SecInfo == SecInfoAll)
    {
        /* We already have a fully formed Security Descriptor */

        pFinalSecDesc = pSecDesc;
        ulFinalSecDescLength = SecDescLength;
    }
    else
    {
        /* Retrieve the existing SD and merge with the incoming one */

        ntError = PvfsGetSecurityDescriptorFile(
                      pCcb,
                      SecInfoAll,
                      (PSECURITY_DESCRIPTOR_RELATIVE)pCurrentSecDescBuffer,
                      &ulCurrentSecDescLength);
        BAIL_ON_NT_STATUS(ntError);

        /* Assume that the new SD is <= the combined size of the current
           SD and the incoming one */

        ntError = RtlSetSecurityDescriptorInfo(
                      SecInfo,
                      pSecDesc,
                      (PSECURITY_DESCRIPTOR_RELATIVE)pCurrentSecDescBuffer,
                      (PSECURITY_DESCRIPTOR_RELATIVE)pNewSecDescBuffer,
                      &ulNewSecDescLength,
                      &gPvfsFileGenericMapping);
        BAIL_ON_NT_STATUS(ntError);

        pFinalSecDesc = (PSECURITY_DESCRIPTOR_RELATIVE)pNewSecDescBuffer;
        ulFinalSecDescLength = ulNewSecDescLength;

    }


    /* Save the combined SD */

#ifdef HAVE_EA_SUPPORT
    ntError = PvfsSetSecurityDescriptorFileXattr(
                  pCcb,
                  pFinalSecDesc,
                  ulFinalSecDescLength);
#else
    ntError = PvfsSetSecurityDescriptorPosix(
                  pCcb,
                  pFinalSecDesc,
                  ulFinalSecDescLength);
#endif

    BAIL_ON_NT_STATUS(ntError);

    PvfsNotifyScheduleFullReport(
        pCcb->pFcb,
        FILE_NOTIFY_CHANGE_SECURITY,
        FILE_ACTION_MODIFIED,
        pCcb->pszFilename);


cleanup:
    if (pIncAbsSecDesc)
    {
        PvfsFreeAbsoluteSecurityDescriptor(&pIncAbsSecDesc);
    }

    return ntError;

error:
    goto cleanup;
}
예제 #14
0
파일: bootdata.c 프로젝트: RPG-7/reactos
static NTSTATUS
RtlpSysVolCheckOwnerAndSecurity(IN HANDLE DirectoryHandle,
                                IN PISECURITY_DESCRIPTOR SecurityDescriptor)
{
    PSECURITY_DESCRIPTOR RelSD = NULL;
    PSECURITY_DESCRIPTOR NewRelSD = NULL;
    PSECURITY_DESCRIPTOR AbsSD = NULL;
#ifdef _WIN64
    BOOLEAN AbsSDAllocated = FALSE;
#endif
    PSID AdminSid = NULL;
    PSID LocalSystemSid = NULL;
    ULONG DescriptorSize;
    ULONG AbsSDSize, RelSDSize = 0;
    PACL Dacl;
    BOOLEAN DaclPresent, DaclDefaulted;
    PSID OwnerSid;
    BOOLEAN OwnerDefaulted;
    ULONG AceIndex;
    PACE Ace = NULL;
    NTSTATUS Status;

    /* find out how much memory we need to allocate for the self-relative
       descriptor we're querying */
    Status = ZwQuerySecurityObject(DirectoryHandle,
                                   OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
                                   NULL,
                                   0,
                                   &DescriptorSize);
    if (Status != STATUS_BUFFER_TOO_SMALL)
    {
        /* looks like the FS doesn't support security... return success */
        Status = STATUS_SUCCESS;
        goto Cleanup;
    }

    /* allocate enough memory for the security descriptor */
    RelSD = RtlpAllocateMemory(DescriptorSize,
                               'dSeS');
    if (RelSD == NULL)
    {
        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    /* query the self-relative security descriptor */
    Status = ZwQuerySecurityObject(DirectoryHandle,
                                   OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
                                   RelSD,
                                   DescriptorSize,
                                   &DescriptorSize);
    if (!NT_SUCCESS(Status))
    {
        /* FIXME - handle the case where someone else modified the owner and/or
                   DACL while we allocated memory. But that should be *very*
                   unlikely.... */
        goto Cleanup;
    }

    /* query the owner and DACL from the descriptor */
    Status = RtlGetOwnerSecurityDescriptor(RelSD,
                                           &OwnerSid,
                                           &OwnerDefaulted);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlGetDaclSecurityDescriptor(RelSD,
                                          &DaclPresent,
                                          &Dacl,
                                          &DaclDefaulted);
    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 local SYSTEM SID */
    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
                                         1,
                                         SECURITY_LOCAL_SYSTEM_RID,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         &LocalSystemSid);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* check if the Administrators are the owner and at least a not-NULL DACL
       is present */
    if (OwnerSid != NULL &&
        RtlEqualSid(OwnerSid,
                    AdminSid) &&
        DaclPresent && Dacl != NULL)
    {
        /* check the DACL for an Allowed ACE for the SYSTEM account */
        AceIndex = 0;
        do
        {
            Status = RtlGetAce(Dacl,
                               AceIndex++,
                               (PVOID*)&Ace);
            if (!NT_SUCCESS(Status))
            {
                Ace = NULL;
            }
            else if (Ace != NULL && Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
            {
                /* check if the the ACE is a set of allowed permissions for the
                   local SYSTEM account */
                if (RtlEqualSid((PSID)(Ace + 1),
                                LocalSystemSid))
                {
                    /* check if the ACE is inherited by noncontainer and
                       container objects, if not attempt to change that */
                    if (!(Ace->Header.AceFlags & OBJECT_INHERIT_ACE) ||
                        !(Ace->Header.AceFlags & CONTAINER_INHERIT_ACE))
                    {
                        Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
                        Status = ZwSetSecurityObject(DirectoryHandle,
                                                     DACL_SECURITY_INFORMATION,
                                                     RelSD);
                    }
                    else
                    {
                        /* all done, we have access */
                        Status = STATUS_SUCCESS;
                    }

                    goto Cleanup;
                }
            }
        } while (Ace != NULL);
    }

    AbsSDSize = DescriptorSize;

    /* because we need to change any existing data we need to convert it to
       an absolute security descriptor first */
    Status = RtlSelfRelativeToAbsoluteSD2(RelSD,
                                          &AbsSDSize);
#ifdef _WIN64
    if (Status == STATUS_BUFFER_TOO_SMALL)
    {
        /* this error code can only be returned on 64 bit builds because
           the size of an absolute security descriptor is greater than the
           size of a self-relative security descriptor */
        ASSERT(AbsSDSize > DescriptorSize);

        AbsSD = RtlpAllocateMemory(DescriptorSize,
                                   'dSeS');
        if (AbsSD == NULL)
        {
            Status = STATUS_NO_MEMORY;
            goto Cleanup;
        }

        AbsSDAllocated = TRUE;

        /* make a raw copy of the self-relative descriptor */
        RtlCopyMemory(AbsSD,
                      RelSD,
                      DescriptorSize);

        /* finally convert it */
        Status = RtlSelfRelativeToAbsoluteSD2(AbsSD,
                                              &AbsSDSize);
    }
    else
#endif
    {
        AbsSD = RelSD;
    }

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

    /* set the owner SID */
    Status = RtlSetOwnerSecurityDescriptor(AbsSD,
                                           AdminSid,
                                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* set the DACL in the security descriptor */
    Status = RtlSetDaclSecurityDescriptor(AbsSD,
                                          TRUE,
                                          SecurityDescriptor->Dacl,
                                          FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* convert it back to a self-relative descriptor, find out how much
       memory we need */
    Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
                                         NULL,
                                         &RelSDSize);
    if (Status != STATUS_BUFFER_TOO_SMALL)
    {
        goto Cleanup;
    }

    /* allocate enough memory for the new self-relative descriptor */
    NewRelSD = RtlpAllocateMemory(RelSDSize,
                                  'dSeS');
    if (NewRelSD == NULL)
    {
        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    /* convert the security descriptor to self-relative format */
    Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
                                         NewRelSD,
                                         &RelSDSize);
    if (Status == STATUS_BUFFER_TOO_SMALL)
    {
        goto Cleanup;
    }

    /* finally attempt to change the security information */
    Status = ZwSetSecurityObject(DirectoryHandle,
                                 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
                                 NewRelSD);

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

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

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

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

#ifdef _WIN64
    if (AbsSDAllocated)
    {
        RtlpFreeMemory(AbsSD,
                       'dSeS');
    }
#endif

    return Status;
}
예제 #15
0
static
NTSTATUS
LsaSrvQueryPolicySecurity(
    PPOLICY_CONTEXT pAccountContext,
    SECURITY_INFORMATION SecurityInformation,
    PSECURITY_DESCRIPTOR_RELATIVE *ppSecurityDescRelative,
    PDWORD pSecurityDescRelativeSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD err = ERROR_SUCCESS;
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = gpLsaSecDesc;
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecurityDesc = NULL;
    PSECURITY_DESCRIPTOR_RELATIVE pSecurityDescRelative = NULL;
    DWORD securityDescRelativeSize = 0;

    err = LwAllocateMemory(
                        SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE,
                        OUT_PPVOID(&pSecurityDesc));
    BAIL_ON_LSA_ERROR(err);

    ntStatus = RtlCreateSecurityDescriptorAbsolute(
                        pSecurityDesc,
                        SECURITY_DESCRIPTOR_REVISION);
    BAIL_ON_NT_STATUS(ntStatus);

    if (SecurityInformation & OWNER_SECURITY_INFORMATION)
    {
        PSID owner = NULL;
        BOOLEAN defaulted = FALSE;

        ntStatus = RtlGetOwnerSecurityDescriptor(
                            pSecDesc,
                            &owner,
                            &defaulted);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = RtlSetOwnerSecurityDescriptor(
                            pSecurityDesc,
                            owner,
                            defaulted);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (SecurityInformation & GROUP_SECURITY_INFORMATION)
    {
        PSID group = NULL;
        BOOLEAN defaulted = FALSE;

        ntStatus = RtlGetGroupSecurityDescriptor(
                            pSecDesc,
                            &group,
                            &defaulted);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = RtlSetGroupSecurityDescriptor(
                            pSecurityDesc,
                            group,
                            defaulted);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (SecurityInformation & DACL_SECURITY_INFORMATION)
    {
        PACL pDacl = NULL;
        BOOLEAN daclPresent = FALSE;
        BOOLEAN defaulted = FALSE;

        ntStatus = RtlGetDaclSecurityDescriptor(
                            pSecDesc,
                            &daclPresent,
                            &pDacl,
                            &defaulted);
        BAIL_ON_NT_STATUS(ntStatus);

        if (daclPresent)
        {
            ntStatus = RtlSetDaclSecurityDescriptor(
                                pSecurityDesc,
                                daclPresent,
                                pDacl,
                                defaulted);
            BAIL_ON_NT_STATUS(ntStatus);
        }
    }

    if (SecurityInformation & SACL_SECURITY_INFORMATION)
    {
        PACL pSacl = NULL;
        BOOLEAN saclPresent = FALSE;
        BOOLEAN defaulted = FALSE;

        ntStatus = RtlGetSaclSecurityDescriptor(
                            pSecDesc,
                            &saclPresent,
                            &pSacl,
                            &defaulted);
        BAIL_ON_NT_STATUS(ntStatus);

        if (saclPresent)
        {
            ntStatus = RtlSetSaclSecurityDescriptor(
                                pSecurityDesc,
                                saclPresent,
                                pSacl,
                                defaulted);
            BAIL_ON_NT_STATUS(ntStatus);
        }
    }

    ntStatus = RtlAbsoluteToSelfRelativeSD(
                        pSecurityDesc,
                        pSecurityDescRelative,
                        &securityDescRelativeSize);
    if (ntStatus == STATUS_BUFFER_TOO_SMALL)
    {
        ntStatus = STATUS_SUCCESS;
    }
    else if (ntStatus != STATUS_SUCCESS)
    {
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = LsaSrvAllocateMemory(
                        OUT_PPVOID(&pSecurityDescRelative),
                        securityDescRelativeSize);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlAbsoluteToSelfRelativeSD(
                        pSecurityDesc,
                        pSecurityDescRelative,
                        &securityDescRelativeSize);
    BAIL_ON_NT_STATUS(ntStatus);

    *ppSecurityDescRelative    = pSecurityDescRelative;
    *pSecurityDescRelativeSize = securityDescRelativeSize;

error:
    if (err || ntStatus)
    {
        if (pSecurityDescRelative)
        {
            LsaSrvFreeMemory(pSecurityDescRelative);
        }

        *ppSecurityDescRelative    = NULL;
        *pSecurityDescRelativeSize = 0;
    }

    LW_SAFE_FREE_MEMORY(pSecurityDesc);

    if (ntStatus == STATUS_SUCCESS &&
        err != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(err);
    }

    return ntStatus;
}
예제 #16
0
파일: SECSYS.C 프로젝트: caidongyun/libs
//----------------------------------------------------------------------
//
// 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;
}
예제 #17
0
static
VOID
CheckDirectorySecurity__(
    _In_ PCWSTR DirectoryName,
    _In_ PSID ExpectedOwner,
    _In_ PSID ExpectedGroup,
    _In_ ULONG AceCount,
    _In_ PCSTR FileAndLine,
    ...)
{
    NTSTATUS Status;
    UNICODE_STRING DirectoryNameString;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE DirectoryHandle;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    ULONG SecurityDescriptorSize;
    PSID Owner;
    PSID Group;
    PACL Dacl;
    PACL Sacl;
    BOOLEAN Present;
    BOOLEAN Defaulted;
    va_list Arguments;

    RtlInitUnicodeString(&DirectoryNameString, DirectoryName);
    InitializeObjectAttributes(&ObjectAttributes,
                               &DirectoryNameString,
                               OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);
    Status = ZwOpenDirectoryObject(&DirectoryHandle,
                                   READ_CONTROL | ACCESS_SYSTEM_SECURITY,
                                   &ObjectAttributes);
    ok_eq_hex(Status, STATUS_SUCCESS);
    if (skip(NT_SUCCESS(Status), "No directory (%ls)\n", DirectoryName))
    {
        return;
    }

    Status = ZwQuerySecurityObject(DirectoryHandle,
                                   OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
                                   NULL,
                                   0,
                                   &SecurityDescriptorSize);
    ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL);
    if (skip(Status == STATUS_BUFFER_TOO_SMALL, "No security size (%ls)\n", DirectoryName))
    {
        ObCloseHandle(DirectoryHandle, KernelMode);
        return;
    }

    SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
                                               SecurityDescriptorSize,
                                               'dSmK');
    ok(SecurityDescriptor != NULL, "Failed to allocate %lu bytes\n", SecurityDescriptorSize);
    if (skip(SecurityDescriptor != NULL, "No memory for descriptor (%ls)\n", DirectoryName))
    {
        ObCloseHandle(DirectoryHandle, KernelMode);
        return;
    }

    Status = ZwQuerySecurityObject(DirectoryHandle,
                                   OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
                                   SecurityDescriptor,
                                   SecurityDescriptorSize,
                                   &SecurityDescriptorSize);
    ok_eq_hex(Status, STATUS_SUCCESS);
    if (NT_SUCCESS(Status))
    {
        Owner = NULL;
        Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
                                               &Owner,
                                               &Defaulted);
        if (ExpectedOwner)
            CheckSid__(Owner, NO_SIZE, ExpectedOwner, FileAndLine);
        ok(Defaulted == FALSE, "Owner defaulted for %ls\n", DirectoryName);

        Group = NULL;
        Status = RtlGetGroupSecurityDescriptor(SecurityDescriptor,
                                               &Group,
                                               &Defaulted);
        if (ExpectedGroup)
            CheckSid__(Group, NO_SIZE, ExpectedGroup, FileAndLine);
        ok(Defaulted == FALSE, "Group defaulted for %ls\n", DirectoryName);

        Dacl = NULL;
        Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
                                              &Present,
                                              &Dacl,
                                              &Defaulted);
        ok_eq_hex(Status, STATUS_SUCCESS);
        ok(Present == TRUE, "DACL not present for %ls\n", DirectoryName);
        ok(Defaulted == FALSE, "DACL defaulted for %ls\n", DirectoryName);
        va_start(Arguments, FileAndLine);
        VCheckAcl__(Dacl, AceCount, FileAndLine, Arguments);
        va_end(Arguments);

        Sacl = NULL;
        Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor,
                                              &Present,
                                              &Sacl,
                                              &Defaulted);
        ok_eq_hex(Status, STATUS_SUCCESS);
        ok(Present == FALSE, "SACL present for %ls\n", DirectoryName);
        ok(Defaulted == FALSE, "SACL defaulted for %ls\n", DirectoryName);
        ok(Sacl == NULL, "Sacl is %p for %ls\n", Sacl, DirectoryName);
    }
    ExFreePoolWithTag(SecurityDescriptor, 'dSmK');
    ObCloseHandle(DirectoryHandle, KernelMode);
}