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; }
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; }
/*++ * @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; }