Deconstructing the Smartcard Removal Policy Service

Windows Vista and Windows Server 2008 introduced a new service that is dedicated to monitoring the removal of smartcards on the system and handling of the event as defined by the Smartcard Removal Policy service (ScRemoveOption) that is configured for the system.  This service (ScPolicySvc) is hosted in one of the svchost.exe processes on the system.

The service recognizes four different registry values; Do nothing (0), Lock session (1) , Logoff session(2) and Disconnect Session(3) – the last only being relevant if the user is connected via a terminal session.

During a smartcard logon, the Smartcard Logon Credential Provider (SmartcardCredentialProvider.dll) is used to gather the smartcard credentials that will be used for authentication.  This CP also writes a registry entry into HKLMSoftwareMicrosoftWindows NTCurrentVersionRemoval Policy that contains the ID of the session being logged on to and the name of the redirected smartcard reader and a value to indicate how many times it has been removed.

The Smartcard Removal Service then monitors this key and spins up a new thread for monitoring that session each time that it detects a value being written to it, it then deletes the subkey containing the session ID once it has picked up the new session it should start monitoring.

Consequently, when a smartcard is removed from a session on the server the thread monitoring that session triggers the appropriate action (Lock/Logoff/Disconnect) and then exits.
If the service detects that the number of times the card has been removed from the reader has changed between the time when the value was written to the registry and the current value for the reader - the removal policy also kicks in for that reader.
You can monitor that behaviour by stopping the ScRemovePolicy and removing/reinserting the smartard after a successful logon - this shold cause the ScRemovePolicy service to disconnect or lock the user as soon as it is started again.

At reconnect the user initially receives an initial "temporary" session ID from the pool of free sessions on the server. This is used during the authentication - it's obviously impossible to match disconnected sessions to the connecting user until the user has authenticated.
if it is determined after authentication that an existing session is present for that user the initial session is ended and the user is reconnected to the existing session. If no existing disconnected session exists then the initial session ID is used for the duration of that session.

ScPolicySvc keeps two lists of sessions it is monitoring; one for the active sessions and one for the inactive sessions.  Usually the thread stops monitoring the session at disconnect but in some circumstances the thread is first moved to the inactive list rather than ended to cater for autoreconnect when the session has lost connectivity rather than having been disconnected on purpose.

A simplified view of the reconnect process is as follows:

  1. A new session is created on the TS when a client connects via RDP - SmartCardCredentialProvider.dll writes the session ID into the Removal Policy registry key (in Hex format)
  2. Once the client has authenticated - the TS subsystem determines if the user has an existing disconnected session and if so, tears down the new session and reconnects the user to the existing session (or pops up a choice window if multiple disconnected sessions exist for that user).
  3. The Smartcard Removal Policy service picks up the session ID used during the authentication from a call to WinStationQueryInformation by passing in the current session ID and getting back the "temporary" session ID used in pWinStationInformation (these may be the same if the user wasn't reconnecting and the "temporary" session ID became the "permanent" session ID).
    It then makes a registry query for that value under HKLMSoftwareMicrosoftWindows NTCurrentVersionRemoval Policy and spins up a thread to start monitoring the associated session if it finds the value and then deletes the registry value when it has consumed it.
    If the service cannot match the ID it just picked up from the call to WinStationQueryInformation to an existing session on the TS the thread is not spun up and the entry is not removed from the registry.

To monitor this in action for troubleshooting purposes, the following can be done:

  • Set up Procmon to monitor HKLMSoftwareMicrosoftWindows NTCurrentVersionRemoval Policy.
  • Create the key HKLMSOFTWAREPoliciesMicrosoftWindowsCertProp and underneath that a DWORD DebugLevel with the value of 0x0000000f
  • Isolate the ScPolicySvc service into its own SVCHOST.exe process by running “sc config ScPolicySvc type= own”

Once the server has rebooted it should be running ScPolicySvc in a separate SVCHost process and be ready for troubleshooting using a debugger like Windbg. 
Attach Windbg to the PID of the svchost.exe process containing the ScPolicySvc service and you should get debug messages at key points during the smartcard removal process.
At the same time you should see LogonUI.exe writing to the Removal Policy registry key and svchost deleting from it shortly afterwards.

[Note: As pointed out to me it would probably be a lot simpler to just stop the ScPolicySvc service and do a Smartcard Logon with Procmon running if you don't want to debug this - that way you can also examine the entry the credential provider writes because it won't be removed until you start it again]


Further reading:



WinStationQueryInformationW function

Comments (7)

  1. Garry Trinder says:

    Hi Adam, if this is time-critical for you then I would really advise opening up a case with Microsoft Developer Support to work on it in realtime.  I’m looking at the Smartcard Removal Policy service in a case I’m working on but I haven’t had the time to dig more into the exact specifics for what is written by the smartcard credential provider as it’s not directly related to the issue I’m working on.

    Are you testing the different smartcard readers from two different clients or from two smartcard readers attached to the same client?  Are you using the same smartcard in each or two different smartcards?

  2. Garry Trinder says:

    One thing that might interest you is that the Smartcard Removal Service subscribes to a session change notification – that’s how it is detecting things like Disconnect or Logoff session.

  3. Garry Trinder says:

    Looking closer at this it seems the entry at the end is the number of times the card has been removed from the reader.  This is to be able to pick up if the card is removed from the reader after the registry entry is written but before the smartcard removal policy starts monitoring it – if there is a difference between the counter in the service and the value in the registry it means that the card was removed before we started monitoring it and we need to disconnect immediately.

  4. Garry Trinder says:

    @Steve: Yes, there is unfortunately not a lot of documentation on this, I assume you're considering writing your own Smartcard Credential Provider….?

    Opening up a support case with developer support and asking specifically about this would probably be your best option – otherwise you can try stopping the service and check on the registry entry that gets written when you log on using the standard smartcard credential provider.

    One thing of note is that the ID for the session is in Hex if I remember correctly, so make sure your CP uses the same format (otherwise you'll get problems when you get above 5 simultaneous logons and user 0xa comes in and you write 10).

  5. adam says:

    Wow, this is exactly what I was looking for!  Thanks so much for posting this.  I need to do something similar in my smart card credential provider but when I watch the "Removal Policy" key in ProcMon, I see that the value being created is a REG_BINARY, instead of the REG_SZ that I would expect given that it is the reader name.  If I want to write the smart card info to that key, should I use a REG_SZ?  Otherwise, are there special considerations I need to take into account as far as formatting the data?  It looks like you’re just outputing UTF16 data into a REG_BINARY, but I want to be sure.

  6. Adam Gross says:

    Ok, I can open up a case.  I tested the smart card readers from a variety of clients, but they all tended to use the same smart card.  I’m not as worried about the session change notification semantics because those seem to work correctly; I’m more worried about the form of the data I have to write out.  If the integer at the end of the stream isn’t the right value, the session will lock right after login because the smart card removal policy will be looking for a smart card reader with the wrong name.

  7. Steve says:

    Hey, to revisit this topic… I'm striking out finding any ms docs on what exactly should be put in registry for card removal service to work properly. Anyone have examples or example code?

Skip to main content