Example #1
0
BOOLEAN
FatCheckManageVolumeAccess (
    _In_ PIRP_CONTEXT IrpContext,
    _In_ PACCESS_STATE AccessState,
    _In_ KPROCESSOR_MODE ProcessorMode
    )

/*++

Routine Description:

    This function checks whether the SID described in the input access state has
    manage volume privilege.

Arguments:

    AccessState - the access state describing the security context to be checked
    
    ProcessorMode - the mode this check should occur against

Return Value:

    BOOLEAN - TRUE if privilege is held and FALSE otherwise

--*/

{
    PRIVILEGE_SET PrivilegeSet;

    PAGED_CODE();

    PrivilegeSet.PrivilegeCount = 1;
    PrivilegeSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
    PrivilegeSet.Privilege[0].Luid = RtlConvertLongToLuid( SE_MANAGE_VOLUME_PRIVILEGE );
    PrivilegeSet.Privilege[0].Attributes = 0;

    if (SePrivilegeCheck( &PrivilegeSet,
                          &AccessState->SubjectSecurityContext,
                          ProcessorMode )) {

        return TRUE;
    }

    UNREFERENCED_PARAMETER( IrpContext );

    return FALSE;
}
Example #2
0
NTSTATUS KphDispatchCreate(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PIO_STACK_LOCATION stackLocation;
    PIO_SECURITY_CONTEXT securityContext;

    stackLocation = IoGetCurrentIrpStackLocation(Irp);
    securityContext = stackLocation->Parameters.Create.SecurityContext;

    dprintf("Client (PID %Iu) is connecting\n", PsGetCurrentProcessId());

    if (KphParameters.SecurityLevel == KphSecurityPrivilegeCheck)
    {
        UCHAR requiredPrivilegesBuffer[FIELD_OFFSET(PRIVILEGE_SET, Privilege) + sizeof(LUID_AND_ATTRIBUTES)];
        PPRIVILEGE_SET requiredPrivileges;

        // Check for SeDebugPrivilege.

        requiredPrivileges = (PPRIVILEGE_SET)requiredPrivilegesBuffer;
        requiredPrivileges->PrivilegeCount = 1;
        requiredPrivileges->Control = PRIVILEGE_SET_ALL_NECESSARY;
        requiredPrivileges->Privilege[0].Luid.LowPart = SE_DEBUG_PRIVILEGE;
        requiredPrivileges->Privilege[0].Luid.HighPart = 0;
        requiredPrivileges->Privilege[0].Attributes = 0;

        if (!SePrivilegeCheck(
            requiredPrivileges,
            &securityContext->AccessState->SubjectSecurityContext,
            Irp->RequestorMode
            ))
        {
            status = STATUS_PRIVILEGE_NOT_HELD;
            dprintf("Client (PID %Iu) was rejected\n", PsGetCurrentProcessId());
        }
    }

    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return status;
}
Example #3
0
BOOLEAN
SeSinglePrivilegeCheck(
    __in LUID PrivilegeValue,
    __in KPROCESSOR_MODE PreviousMode
    )

/*++

Routine Description:

    This function will check for the passed privilege value in the
    current context.

Arguments:

    PrivilegeValue - The value of the privilege being checked.


Return Value:

    TRUE - The current subject has the desired privilege.

    FALSE - The current subject does not have the desired privilege.
--*/

{
    BOOLEAN AccessGranted;
    PRIVILEGE_SET RequiredPrivileges;
    SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;

    PAGED_CODE();

    //
    // Make sure the caller has the privilege to make this
    // call.
    //

    RequiredPrivileges.PrivilegeCount = 1;
    RequiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY;
    RequiredPrivileges.Privilege[0].Luid = PrivilegeValue;
    RequiredPrivileges.Privilege[0].Attributes = 0;

    SeCaptureSubjectContext( &SubjectSecurityContext );

    AccessGranted = SePrivilegeCheck(
                        &RequiredPrivileges,
                        &SubjectSecurityContext,
                        PreviousMode
                        );

    if ( PreviousMode != KernelMode ) {

        SePrivilegedServiceAuditAlarm (
            NULL,
            &SubjectSecurityContext,
            &RequiredPrivileges,
            AccessGranted
            );
    }


    SeReleaseSubjectContext( &SubjectSecurityContext );

    return( AccessGranted );

}
Example #4
0
BOOLEAN
SeCheckPrivilegedObject(
    __in LUID PrivilegeValue,
    __in HANDLE ObjectHandle,
    __in ACCESS_MASK DesiredAccess,
    __in KPROCESSOR_MODE PreviousMode
    )

/*++

Routine Description:

    This function will check for the passed privilege value in the
    current context, and generate audits as appropriate.

Arguments:

    PrivilegeValue - The value of the privilege being checked.

    Object - Specifies a pointer to the object being accessed.

    ObjectHandle - Specifies the object handle being used.

    DesiredAccess - The desired access mask, if any

    PreviousMode - The previous processor mode


Return Value:

    TRUE - The current subject has the desired privilege.

    FALSE - The current subject does not have the desired privilege.
--*/

{
    BOOLEAN AccessGranted;
    PRIVILEGE_SET RequiredPrivileges;
    SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;

    PAGED_CODE();

    //
    // Make sure the caller has the privilege to make this
    // call.
    //

    RequiredPrivileges.PrivilegeCount = 1;
    RequiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY;
    RequiredPrivileges.Privilege[0].Luid = PrivilegeValue;
    RequiredPrivileges.Privilege[0].Attributes = 0;

    SeCaptureSubjectContext( &SubjectSecurityContext );

    AccessGranted = SePrivilegeCheck(
                        &RequiredPrivileges,
                        &SubjectSecurityContext,
                        PreviousMode
                        );

    if ( PreviousMode != KernelMode ) {

        SePrivilegeObjectAuditAlarm(
            ObjectHandle,
            &SubjectSecurityContext,
            DesiredAccess,
            &RequiredPrivileges,
            AccessGranted,
            PreviousMode
            );

    }


    SeReleaseSubjectContext( &SubjectSecurityContext );

    return( AccessGranted );
}
Example #5
0
NTSTATUS
FatExplicitDeviceAccessGranted (
    IN PIRP_CONTEXT IrpContext,
    IN PDEVICE_OBJECT DeviceObject,
    IN PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE ProcessorMode
)

/*++

Routine Description:

    This function asks whether the SID described in the input access state has
    been granted any explicit access to the given device object.  It does this
    by acquiring a token stripped of its ability to acquire access via the
    Everyone SID and re-doing the access check.

Arguments:

    DeviceObject - the device whose ACL will be checked

    AccessState - the access state describing the security context to be checked

    ProcessorMode - the mode this check should occur against

Return Value:

    NTSTATUS - Indicating whether explicit access was granted.

--*/

{
    NTSTATUS Status;
    BOOLEAN Result;

    PACCESS_TOKEN OriginalAccessToken;
    PACCESS_TOKEN RestrictedAccessToken;

    PACCESS_TOKEN *EffectiveToken;

    PRIVILEGE_SET PrivilegeSet;

    ACCESS_MASK GrantedAccess;

    //
    //  If the access state indicates that specific access other
    //  than traverse was acquired, either Everyone does have such
    //  access or explicit access was granted.  In both cases, we're
    //  happy to let this proceed.
    //

    if (AccessState->PreviouslyGrantedAccess & (SPECIFIC_RIGHTS_ALL ^
            FILE_TRAVERSE)) {

        return STATUS_SUCCESS;
    }

    //
    //  If the manage volume privilege is held, this also permits access.
    //

    PrivilegeSet.PrivilegeCount = 1;
    PrivilegeSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
    PrivilegeSet.Privilege[0].Luid = RtlConvertLongToLuid( SE_MANAGE_VOLUME_PRIVILEGE );
    PrivilegeSet.Privilege[0].Attributes = 0;

    if (SePrivilegeCheck( &PrivilegeSet,
                          &AccessState->SubjectSecurityContext,
                          ProcessorMode )) {

        return STATUS_SUCCESS;
    }

    //
    //  Capture the subject context as a prelude to everything below.
    //

    SeLockSubjectContext( &AccessState->SubjectSecurityContext );

    //
    //  Convert the token in the subject context into one which does not
    //  acquire access through the Everyone SID.
    //
    //  The logic for deciding which token is effective comes from
    //  SeQuerySubjectContextToken; since there is no natural way
    //  of getting a pointer to it, do it by hand.
    //

    if (ARGUMENT_PRESENT( AccessState->SubjectSecurityContext.ClientToken )) {
        EffectiveToken = &AccessState->SubjectSecurityContext.ClientToken;
    } else {
        EffectiveToken = &AccessState->SubjectSecurityContext.PrimaryToken;
    }

    OriginalAccessToken = *EffectiveToken;
    Status = FatCreateRestrictEveryoneToken( OriginalAccessToken, &RestrictedAccessToken );

    if (!NT_SUCCESS(Status)) {

        SeReleaseSubjectContext( &AccessState->SubjectSecurityContext );
        return Status;
    }

    //
    //  Now see if the resulting context has access to the device through
    //  its explicitly granted access.  We swap in our restricted token
    //  for this check as the effective client token.
    //

    *EffectiveToken = RestrictedAccessToken;

    Result = SeAccessCheck( DeviceObject->SecurityDescriptor,
                            &AccessState->SubjectSecurityContext,
                            FALSE,
                            AccessState->OriginalDesiredAccess,
                            0,
                            NULL,
                            IoGetFileObjectGenericMapping(),
                            ProcessorMode,
                            &GrantedAccess,
                            &Status );

    *EffectiveToken = OriginalAccessToken;

    //
    //  Cleanup and return.
    //

    SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );
    ObDereferenceObject( RestrictedAccessToken );

    return Status;
}