How can I distinguish between logon failures caused by disabled accounts, expired accounts, and locked-out accounts?
If your users' workstations use Kerberos to authenticate to your domain controller (DC), you won't be able to distinguish between the three logon-failure reasons you mention. The Account Logon Security log category logs Kerberos authentication failures with Request for Comments (RFC) 1510's standard Kerberos failure codes, which lack that kind of granularity. On Windows 2000 Server, event ID 676 records all three types of authentication failures under the same failure code: 18. On Windows Server 2003, failure-type event ID 672 replaces event ID 676.
The Logon/Logoff Security log category isn't really any help either. Although the category does log a specific error code for each type of failure, Windows logs Logon/Logoff events where the logon occurs, not where the authentication takes place. Logon occurs on the workstation, which means that to find the logon failure reason, you'd have to track each Kerberos event ID 676 (Win2K) or failure-type event ID 672 (Windows 2003) with failure code 18 to the appropriate workstation and find the corresponding Logon/Logoff event on that workstation.
If your user workstations are Win2K or later, they're authenticating via Kerberos. But pre-Win2K workstations authenticate via NT LAN Manager. NTLM authentication failures provide a different error code for each reason a logon might fail. Look for event ID 681 on Win2K DCs and for failure-type event ID 680 on Windows 2003 DCs, then check the error code in the event's description. For disabled accounts, the error code will be 3221225586; for expired accounts, 3221225875; and for locked-out accounts, 3221226036.