Because of client-side interpolation and prediction, the client isn't on the same game state as the server, just an approximation of it. It's the tradeoff you have to make for a smooth game experience.
The server can do a best effort attempt at rewinding the game state and take into account how the client is interpolating the world, but it gets very complicated as game complexity goes up.
Someone correct me if I'm wrong, but I believe the Source engine does that for the attacker and the victim, but ignores all other entities for the ray casting (so it can only really prevent shooting through the map walls)
Yes. There are two issues here - "don't trust the client", and hiding lag. Not trusting the client is mostly about re-doing some checks the client supposedly already did. It's work, but it's not conceptually hard.
Hiding lag requires guessing about what moving objects are likely to do. This works best for systems with a limited set of moving objects, such as players and bullets. As the author points out, bullets are handled as a very special case.
I've done some work on this inside a Second Life / Open Simulator viewer. That's a very general system - anything can potentially move. You can make guns and shoot things, but the system has no idea of "bullet", just physics. The server is authoritative about everything except which way an avatar is facing. So turning is fast, but movement only happens after one round trip to the server. Round trip delay is typically 40-200ms. The problem is hiding that.
The server sends the viewer updates with position/rotation, velocity/rotational velocity, and linear acceleration. That last makes projectiles describe an arc under gravity without server side updates.
When an update comes in, the moving object has to be yanked back to where the server says it is. There are situations in which the predictor isn't very good, especially in the presence of jitter. And, the worst case, a region crossing, where there are no updates for 500ms-2000ms during the server handoff. The original predictor would sometimes put vehicles far into the air or into the ground for one update cycle. The predictor was using the last velocity, which is noisy as a vehicle bumps along a road following the outputs from the physics engine. As in real life, there's vibration. The last velocity, intended to be used only for 1/45 second, was being extrapolated to 500ms-2000ms, or sometimes as much as 100x the time it was intended for. So, low-pass filtering and a error metric was added to make vehicle movement look sane. The illusion can be maintained reasonably well up to about 200ms of lag, but beyond that, it shows as "rubber banding".
Shooters just don't work well in a system this general. Archery is sort of OK.
The server can do a best effort attempt at rewinding the game state and take into account how the client is interpolating the world, but it gets very complicated as game complexity goes up.
Someone correct me if I'm wrong, but I believe the Source engine does that for the attacker and the victim, but ignores all other entities for the ray casting (so it can only really prevent shooting through the map walls)