That is indeed what happens. When you fire a shot, for the sake of player feedback the client will determine if the hit was made, and render the game accordingly.
The server can invalidate that result if it disagrees. This is why very occasionally, in high-lag situations, you might shoot a layer, see blood, but the player takes no damage.
In this case the validation is being done in real-time, and the prediction is only ever performed for feedback-critical actions (shooting, movement, reloading, etc).
This does happen in some games - the Halo series comes to mind. A player is determined to be the "server" based on network conditions, and the plus side of it is also that should the server drop, the game will only be momentarily interrupted and you can select a new player to act as the server.
This doesn't work in all instances - most games using this mechanism are fairly small in terms of player count, since the server is not of a guaranteed performance level, the connection its on is probably a home-based broadband connection at best, and it has to invest a lot of cycles into rendering the game. For larger games (say, the Battlefield series) the hardware required makes it such that the system is infeasible. Instead you have extremely beefy hardware running dedicated servers - headless, non-rendering servers that can throw every cycle it has into serving the game.
The server can invalidate that result if it disagrees. This is why very occasionally, in high-lag situations, you might shoot a layer, see blood, but the player takes no damage.
In this case the validation is being done in real-time, and the prediction is only ever performed for feedback-critical actions (shooting, movement, reloading, etc).