I would think the best way to do this is using a central license server (which I believe is what for example 3DStudioMSX uses) issuing tickets ala. X.509 or Kerberos?
When coming up with a license system, make sure to account for client hardware and software problems as well.
e.g.:
1) Client program crashes. Upon restart, will it check out a second/third/fourth/whatever license, or keep using the same one?
2) People periodically upgrade their computers. Keep this in mind when assigning licenses to a client - can they un-register the program as well?
3) Furthermore -- Computers (and especially harddrives) can die. If you have a system where the client can register/unregister itself, keep in mind that there will be situations where a machine is no longer capable of unregistering itself with the server simply because it won't boot up.
Possible solution(s):
- Hand out a time-limited license, that expires after a certain time so dead machines won't perpetually take up a license
- Have an admin console on the server where you can force-revoke / reassign an existing license, freeing it up for another user. (Possibly sending a deactivation signal to the user currently using the license)
- Possibly build in a few grace licenses: e.g. If you have 10 licenses, allow 12 clients to use it but if there are more than the 10 licensed connection start throwing nag-screens upon application launch to notify the users about exceeding the server licenses. Meanwhile you can allow them to use the two grace licenses anyway.
(This is what the IBM AS/400 client express does)