Rework permission checking architecture

Execute each permission checker in series with the list of all remaining
permissions. Permission checker returns the new list of remaining
permissions. If the list is ever empty, stop processing and return
failure. If the list still has permissions after processing all
permission checkers, then access is allowed.