예제 #1
1
파일: access.c 프로젝트: Gaikokujin/WinNT4
BOOLEAN
SrvIsAdmin(
    CtxtHandle  Handle
)
/*++

Routine Description:

    Returns TRUE if the user represented by Handle is an
      administrator

Arguments:

    Handle - Represents the user we're interested in

Return Value:

    TRUE if the user is an administrator.  FALSE otherwise.

--*/
{
    NTSTATUS                 status;
    SECURITY_SUBJECT_CONTEXT SubjectContext;
    ACCESS_MASK              GrantedAccess;
    GENERIC_MAPPING          Mapping = {   FILE_GENERIC_READ,
                                           FILE_GENERIC_WRITE,
                                           FILE_GENERIC_EXECUTE,
                                           FILE_ALL_ACCESS
                                       };
    HANDLE                   NullHandle = NULL;
    BOOLEAN                  retval  = FALSE;

    PAGED_CODE();

    //
    // Impersonate the client
    //
    status = ImpersonateSecurityContext( &Handle );

    if( !NT_SUCCESS( status ) )
        return FALSE;

    SeCaptureSubjectContext( &SubjectContext );

    retval = SeAccessCheck( &SrvAdminSecurityDescriptor,
                            &SubjectContext,
                            FALSE,
                            FILE_GENERIC_READ,
                            0,
                            NULL,
                            &Mapping,
                            UserMode,
                            &GrantedAccess,
                            &status );

    SeReleaseSubjectContext( &SubjectContext );

    //
    // Revert back to our original identity
    //
    NtSetInformationThread( NtCurrentThread( ),
                            ThreadImpersonationToken,
                            &NullHandle,
                            sizeof(NullHandle)
                          );
    return retval;
}
예제 #2
0
파일: ps.cpp 프로젝트: catterpiler74/gr8os
KESYSAPI
PPROCESS
KEAPI
PsCreateProcess(
	)
/*++
	Create process allocating new space for PROCESS
--*/
{
	if (!SUCCESS(SeAccessCheck (SE_1_CREATE_PROCESS, 0)))
		return NULL;

	PPROCESS Process = (PPROCESS) ExAllocateHeap( FALSE, sizeof(PROCESS) );
	PspCreateProcess( Process );
	MmCreateAddressSpace( Process );

	PVOID Arguments[1] = {
		Process
	};

	ExProcessCallbackList (
		&PsCreateProcessCallbackList,
		3,
		Arguments
		);

	return Process;
}
예제 #3
0
BOOLEAN
NTAPI
ObpCheckTraverseAccess(IN PVOID Object,
                       IN ACCESS_MASK TraverseAccess,
                       IN PACCESS_STATE AccessState OPTIONAL,
                       IN BOOLEAN LockHeld,
                       IN KPROCESSOR_MODE AccessMode,
                       OUT PNTSTATUS AccessStatus)
{
    POBJECT_HEADER ObjectHeader;
    POBJECT_TYPE ObjectType;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    BOOLEAN SdAllocated;
    BOOLEAN Result;
    ACCESS_MASK GrantedAccess = 0;
    PPRIVILEGE_SET Privileges = NULL;
    NTSTATUS Status;
    PAGED_CODE();

    /* Get the header and type */
    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
    ObjectType = ObjectHeader->Type;

    /* Get the security descriptor */
    Status = ObGetObjectSecurity(Object, &SecurityDescriptor, &SdAllocated);
    if (!NT_SUCCESS(Status))
    {
        /* We failed */
        *AccessStatus = Status;
        return FALSE;
    }

    /* Lock the security context */
    SeLockSubjectContext(&AccessState->SubjectSecurityContext);

    /* Now do the entire access check */
    Result = SeAccessCheck(SecurityDescriptor,
                           &AccessState->SubjectSecurityContext,
                           TRUE,
                           TraverseAccess,
                           0,
                           &Privileges,
                           &ObjectType->TypeInfo.GenericMapping,
                           AccessMode,
                           &GrantedAccess,
                           AccessStatus);
    if (Privileges)
    {
        /* We got privileges, append them to the access state and free them */
        Status = SeAppendPrivileges(AccessState, Privileges);
        SeFreePrivileges(Privileges);
    }

    /* We're done, unlock the context and release security */
    SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
    ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated);
    return Result;
}
예제 #4
0
파일: ps.cpp 프로젝트: catterpiler74/gr8os
KESYSAPI
PTHREAD
KEAPI
PsCreateThread(
	IN  PPROCESS OwningProcess,
	IN  PVOID  StartRoutine,
	IN  PVOID  StartContext
	)
/*++
	Create new thread allocating new space for THREAD
--*/
{
	if (!SUCCESS(SeAccessCheck (SE_1_CREATE_THREAD, 0)))
		return NULL;

	PTHREAD NewThread = (PTHREAD) ExAllocateHeap( FALSE, sizeof(THREAD) );
	KeZeroMemory( NewThread, sizeof(THREAD) );

	STATUS Status = SeInheritAccessTokenProcess (
		OwningProcess,
		OwningProcess->AccessToken->Privileges1,
		OwningProcess->AccessToken->Privileges2,
		&NewThread->AccessToken
		);

	if (!SUCCESS(Status))
	{
		ExFreeHeap (NewThread);
		return NULL;
	}

	PspCreateThread( NewThread, OwningProcess, StartRoutine, StartContext );

	PVOID Arguments[3] = {
		NewThread,
		StartRoutine,
		StartContext
	};

	ExProcessCallbackList (
		&PsCreateThreadCallbackList,
		3,
		Arguments
		);

	return NewThread;
}
예제 #5
0
파일: acchksup.c 프로젝트: Moteesh/reactos
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;

    PACCESS_TOKEN OriginalAccessToken;
    PACCESS_TOKEN RestrictedAccessToken;
    
    PACCESS_TOKEN *EffectiveToken;
    
    ACCESS_MASK GrantedAccess;

    PAGED_CODE();

    UNREFERENCED_PARAMETER( IrpContext );

    //
    //  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.
    //

    if (FatCheckManageVolumeAccess( IrpContext,
                                    AccessState,
                                    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;
    
#ifdef _MSC_VER
#pragma prefast( suppress: 28175, "we're a file system, this is ok to touch" )
#endif
    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;
}
예제 #6
0
파일: create.c 프로젝트: BillTheBest/WinNT4
IO_STATUS_BLOCK
MsCreateClientEnd (
    IN PFCB Fcb,
    IN PFILE_OBJECT FileObject,
    IN ACCESS_MASK DesiredAccess,
    IN USHORT ShareAccess,
    IN PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE RequestorMode,
    IN PETHREAD UserThread
    )

/*++

Routine Description:

    This routine performs the operation for opening the client end of a
    mailslot.  This routine does not complete the IRP, it performs the
    function and then returns a status.

Arguments:

    Fcb - Supplies the FCB for the mailslot being accessed.

    FileObject - Supplies the file object associated with the client end.

    DesiredAccess - Supplies the caller's desired access.

    ShareAccess - Supplies the caller's share access.

Return Value:

    IO_STATUS_BLOCK - Returns the appropriate status for the operation

--*/

{
    IO_STATUS_BLOCK iosb;
    PCCB ccb;

    BOOLEAN accessGranted;
    ACCESS_MASK grantedAccess;
    UNICODE_STRING name;
    PPRIVILEGE_SET Privileges = NULL;
    BOOLEAN shareAccessUpdated = FALSE;

    PAGED_CODE();
    DebugTrace(+1, Dbg, "MsCreateClientEnd\n", 0 );

    try {

        //
        //  First do an access check for the user against the Fcb
        //

        SeLockSubjectContext( &AccessState->SubjectSecurityContext );

        accessGranted = SeAccessCheck( Fcb->SecurityDescriptor,
                                       &AccessState->SubjectSecurityContext,
                                       TRUE,                        // Tokens are locked
                                       DesiredAccess,
                                       0,
                                       &Privileges,
                                       IoGetFileObjectGenericMapping(),
                                       RequestorMode,
                                       &grantedAccess,
                                       &iosb.Status );

        if (Privileges != NULL) {

              (VOID) SeAppendPrivileges(
                         AccessState,
                         Privileges
                         );

            SeFreePrivileges( Privileges );
        }

        if (accessGranted) {
            AccessState->PreviouslyGrantedAccess |= grantedAccess;
            AccessState->RemainingDesiredAccess &= ~grantedAccess;
        }

        RtlInitUnicodeString( &name, L"Mailslot" );

        SeOpenObjectAuditAlarm( &name,
                                NULL,
                                &FileObject->FileName,
                                Fcb->SecurityDescriptor,
                                AccessState,
                                FALSE,
                                accessGranted,
                                RequestorMode,
                                &AccessState->GenerateOnClose );


        SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );

        if (!accessGranted) {

            DebugTrace(0, Dbg, "Access Denied\n", 0 );

            try_return( iosb.Status );
        }

        //
        // Now make sure our share access is okay.
        //

        if (!NT_SUCCESS(iosb.Status = IoCheckShareAccess( DesiredAccess,
                                                          ShareAccess,
                                                          FileObject,
                                                          &Fcb->ShareAccess,
                                                          TRUE ))) {

            DebugTrace(0, Dbg, "Sharing violation\n", 0);

            try_return( NOTHING );
        }

        shareAccessUpdated = TRUE;

        //
        // Create a CCB for this client.
        //

        ccb = MsCreateCcb( Fcb );

        //
        // Set the file object back pointers and our pointer to the
        // server file object.
        //

        MsSetFileObject( FileObject,
                         ccb,
                         NULL );

        ccb->FileObject = FileObject;

        //
        //  And set our return status
        //

        iosb.Status = STATUS_SUCCESS;
        iosb.Information = FILE_OPENED;


    try_exit: NOTHING;
    } finally {

        DebugTrace(-1, Dbg, "MsCreateClientEnd -> %08lx\n", iosb.Status);

        if (!NT_SUCCESS(iosb.Status) || AbnormalTermination()) {
            if (shareAccessUpdated) {
                IoRemoveShareAccess( FileObject, &Fcb->ShareAccess );
            }
        }

    }

    return iosb;
}
예제 #7
0
/*++
* @name ObCheckObjectAccess
*
*     The ObCheckObjectAccess routine <FILLMEIN>
*
* @param Object
*        <FILLMEIN>
*
* @param AccessState
*        <FILLMEIN>
*
* @param LockHeld
*        <FILLMEIN>
*
* @param AccessMode
*        <FILLMEIN>
*
* @param ReturnedStatus
*        <FILLMEIN>
*
* @return TRUE if access was granted, FALSE otherwise.
*
* @remarks None.
*
*--*/
BOOLEAN
NTAPI
ObCheckObjectAccess(IN PVOID Object,
                    IN OUT PACCESS_STATE AccessState,
                    IN BOOLEAN LockHeld,
                    IN KPROCESSOR_MODE AccessMode,
                    OUT PNTSTATUS ReturnedStatus)
{
    POBJECT_HEADER ObjectHeader;
    POBJECT_TYPE ObjectType;
    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
    BOOLEAN SdAllocated;
    NTSTATUS Status;
    BOOLEAN Result;
    ACCESS_MASK GrantedAccess;
    PPRIVILEGE_SET Privileges = NULL;
    PAGED_CODE();

    /* Get the object header and type */
    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
    ObjectType = ObjectHeader->Type;

    /* Get security information */
    Status = ObGetObjectSecurity(Object, &SecurityDescriptor, &SdAllocated);
    if (!NT_SUCCESS(Status))
    {
        /* Return failure */
        *ReturnedStatus = Status;
        return FALSE;
    }
    else if (!SecurityDescriptor)
    {
        /* Otherwise, if we don't actually have an SD, return success */
        *ReturnedStatus = Status;
        return TRUE;
    }

    /* Lock the security context */
    SeLockSubjectContext(&AccessState->SubjectSecurityContext);

    /* Now do the entire access check */
    Result = SeAccessCheck(SecurityDescriptor,
                           &AccessState->SubjectSecurityContext,
                           TRUE,
                           AccessState->RemainingDesiredAccess,
                           AccessState->PreviouslyGrantedAccess,
                           &Privileges,
                           &ObjectType->TypeInfo.GenericMapping,
                           AccessMode,
                           &GrantedAccess,
                           ReturnedStatus);
    if (Privileges)
    {
        /* We got privileges, append them to the access state and free them */
        Status = SeAppendPrivileges(AccessState, Privileges);
        SeFreePrivileges(Privileges);
    }

    /* Check if access was granted */
    if (Result)
    {
        /* Update the access state */
        AccessState->RemainingDesiredAccess &= ~(GrantedAccess |
                                                 MAXIMUM_ALLOWED);
        AccessState->PreviouslyGrantedAccess |= GrantedAccess;
    }

    /* Do audit alarm */
    SeOpenObjectAuditAlarm(&ObjectType->Name,
                           Object,
                           NULL,
                           SecurityDescriptor,
                           AccessState,
                           FALSE,
                           Result,
                           AccessMode,
                           &AccessState->GenerateOnClose);

    /* We're done, unlock the context and release security */
    SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
    ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated);
    return Result;
}
예제 #8
0
BOOLEAN
NTAPI
ObpCheckObjectReference(IN PVOID Object,
                        IN OUT PACCESS_STATE AccessState,
                        IN BOOLEAN LockHeld,
                        IN KPROCESSOR_MODE AccessMode,
                        OUT PNTSTATUS AccessStatus)
{
    POBJECT_HEADER ObjectHeader;
    POBJECT_TYPE ObjectType;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    BOOLEAN SdAllocated;
    BOOLEAN Result;
    ACCESS_MASK GrantedAccess = 0;
    PPRIVILEGE_SET Privileges = NULL;
    NTSTATUS Status;
    PAGED_CODE();

    /* Get the header and type */
    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
    ObjectType = ObjectHeader->Type;

    /* Get the security descriptor */
    Status = ObGetObjectSecurity(Object, &SecurityDescriptor, &SdAllocated);
    if (!NT_SUCCESS(Status))
    {
        /* We failed */
        *AccessStatus = Status;
        return FALSE;
    }

    /* Lock the security context */
    SeLockSubjectContext(&AccessState->SubjectSecurityContext);

    /* Now do the entire access check */
    Result = SeAccessCheck(SecurityDescriptor,
                           &AccessState->SubjectSecurityContext,
                           TRUE,
                           AccessState->RemainingDesiredAccess,
                           AccessState->PreviouslyGrantedAccess,
                           &Privileges,
                           &ObjectType->TypeInfo.GenericMapping,
                           AccessMode,
                           &GrantedAccess,
                           AccessStatus);
    if (Result)
    {
        /* Update the access state */
        AccessState->RemainingDesiredAccess &= ~GrantedAccess;
        AccessState->PreviouslyGrantedAccess |= GrantedAccess;
    }

    /* Check if we have an SD */
    if (SecurityDescriptor)
    {
        /* Do audit alarm */
#if 0
        SeObjectReferenceAuditAlarm(&AccessState->OperationID,
                                    Object,
                                    SecurityDescriptor,
                                    &AccessState->SubjectSecurityContext,
                                    AccessState->RemainingDesiredAccess |
                                    AccessState->PreviouslyGrantedAccess,
                                    ((PAUX_ACCESS_DATA)(AccessState->AuxData))->
                                    PrivilegeSet,
                                    Result,
                                    AccessMode);
#endif
    }

    /* We're done, unlock the context and release security */
    SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
    ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated);
    return Result;
}
예제 #9
0
NTSTATUS
NTAPI
PspSetPrimaryToken(IN PEPROCESS Process,
                   IN HANDLE TokenHandle OPTIONAL,
                   IN PACCESS_TOKEN Token OPTIONAL)
{
    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
    BOOLEAN IsChild;
    PACCESS_TOKEN NewToken = Token;
    NTSTATUS Status, AccessStatus;
    BOOLEAN Result, SdAllocated;
    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
    SECURITY_SUBJECT_CONTEXT SubjectContext;
    PSTRACE(PS_SECURITY_DEBUG, "Process: %p Token: %p\n", Process, Token);

    /* Make sure we got a handle */
    if (TokenHandle)
    {
        /* Reference it */
        Status = ObReferenceObjectByHandle(TokenHandle,
                                           TOKEN_ASSIGN_PRIMARY,
                                           SeTokenObjectType,
                                           PreviousMode,
                                           (PVOID*)&NewToken,
                                           NULL);
        if (!NT_SUCCESS(Status)) return Status;
    }

    /* Check if this is a child */
    Status = SeIsTokenChild(NewToken, &IsChild);
    if (!NT_SUCCESS(Status))
    {
        /* Failed, dereference */
        if (TokenHandle) ObDereferenceObject(NewToken);
        return Status;
    }

    /* Check if this was an independent token */
    if (!IsChild)
    {
        /* Make sure we have the privilege to assign a new one */
        if (!SeSinglePrivilegeCheck(SeAssignPrimaryTokenPrivilege,
                                    PreviousMode))
        {
            /* Failed, dereference */
            if (TokenHandle) ObDereferenceObject(NewToken);
            return STATUS_PRIVILEGE_NOT_HELD;
        }
    }

    /* Assign the token */
    Status = PspAssignPrimaryToken(Process, NULL, NewToken);
    if (NT_SUCCESS(Status))
    {
        /*
         * We need to completely reverify if the process still has access to
         * itself under this new token.
         */
        Status = ObGetObjectSecurity(Process,
                                     &SecurityDescriptor,
                                     &SdAllocated);
        if (NT_SUCCESS(Status))
        {
            /* Setup the security context */
            SubjectContext.ProcessAuditId = Process;
            SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process);
            SubjectContext.ClientToken = NULL;

            /* Do the access check */
            Result = SeAccessCheck(SecurityDescriptor,
                                   &SubjectContext,
                                   FALSE,
                                   MAXIMUM_ALLOWED,
                                   0,
                                   NULL,
                                   &PsProcessType->TypeInfo.GenericMapping,
                                   PreviousMode,
                                   &Process->GrantedAccess,
                                   &AccessStatus);

            /* Dereference the token and let go the SD */
            ObFastDereferenceObject(&Process->Token,
                                    SubjectContext.PrimaryToken);
            ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated);

            /* Remove access if it failed */
            if (!Result) Process->GrantedAccess = 0;

            /* Setup granted access */
            Process->GrantedAccess |= (PROCESS_VM_OPERATION |
                                       PROCESS_VM_READ |
                                       PROCESS_VM_WRITE |
                                       PROCESS_QUERY_INFORMATION |
                                       PROCESS_TERMINATE |
                                       PROCESS_CREATE_THREAD |
                                       PROCESS_DUP_HANDLE |
                                       PROCESS_CREATE_PROCESS |
                                       PROCESS_SET_INFORMATION |
                                       STANDARD_RIGHTS_ALL |
                                       PROCESS_SET_QUOTA);
        }
    }

    /* Dereference the token */
    if (TokenHandle) ObDereferenceObject(NewToken);
    return Status;
}