This article describes how use GINA Logon hooks to perform custom actions that require the user's Winlogon and password prior to performing the domain logon. This for example can allow the Windows logon to perform 802.1X/WPA2 authentication using the domain login/pass credentials and establish network connection before contacting the AD server to authenticate the user.
GINA stands for Graphical Identification and Authentication dynamic-link library. The GINA is a replaceable DLL component that is loaded by the Winlogon executable. The purpose of a GINA DLL is to provide customizable user identification and authentication procedures. The default GINA does this by delegating SAS event monitoring to Winlogon, which receives and processes CTL+ALT+DEL secure attention sequences (SASs). A custom GINA is responsible for setting itself up to receive SAS events (other than the default CTRL+ALT+DEL SAS event) and notifying Winlogon when SAS events occur. Winlogon will evaluate its state to determine what is required to process the custom GINA's SAS. This processing usually includes calls to the GINA's SAS processing functions.
To customize the Windows logon process, we just need to overwrite some GINA functions. For this, we need to create a GINA DLL with the required set of exported functions and provide our customized implementation of some functions.
The approach is to make the replacement GINA DLL load the original GINA DLL and obtain pointers to the original GINA functions. Then, our customized GINA DLL will export the required GINA functions by calling the original GINA functions. Where customization is needed, our GINA function will execute custom code before or after calling the original GINA function.
In this example, we will create a GINA function that will do something with the user's login/password before performing the domain logon. All other GINA functions will just be pass-thru to the original GINA DLL.
The best way to add custom winlogon functionality is to start from a GINA stub. You can get a GINA stub from Microsoft Platform SDK for Windows XP SP2. You can find it under :
C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Samples\Security\GINA\GinaStub
To build the GINA DLL, you need to have Microsoft Visual C/C++ installed.
Edit the Makfefile in the GinaStub directory and remove the Windows NT condition. The Makefile should look like this :
!include <win32.mak> proj=ginastub all: $(proj).dll $(proj).obj: $(proj).c $(cc) $(cdebug) $(cflags) $*.c $(proj).lib: $(proj).obj $(proj).def $(implib) -machine:$(CPU) -def:$(proj).def -out:$(proj).lib $(proj).dll: $(proj).obj $(link) $(ldebug) $(dlllflags) $(guilibsdll) \ $** -out:$(proj).dll -def:$(proj).def
From the MSVC++ console, cd to the GinaStub directory then type :
Winlogon calls the WlxLoggedOutSAS GINA function when an event occurs while no users are logged in the system (e.g. user inserts Smart card, or presses ALT-CTRL-DEL). To detect which exact event resulted in the call, the WlxLoggedOutSAS GINA function checks the variable dwSasType. If it equals WLX_SAS_TYPE_CTRL_ALT_DEL, the login/password input box is displayed. From here, the function takes care of authenticating the user and setting up its environment.
int WlxLoggedOutSAS( __in PVOID pWlxContext, __in DWORD dwSasType, __out PLUID pAuthenticationId, __inout PSID pLogonSid, __out PDWORD pdwOptions, __out PHANDLE phToken, __out PWLX_MPR_NOTIFY_INFO pNprNotifyInfo, __out PVOID *pProfile );
One way thus to obtain the login/password pair before performing the logon, is to create our own login/password box (using WlxDialogBoxParam) to get the user credentials, then use the entered credentials to do custom processing before performing logon by calling LsaLogonUser.
This is much easier than the previous case. All we have to do is call the original WlxLoggedOutSAS function then get the login/password/domain from pMprNotifyInfo variable set by .
pMprNotifyInfo->pszUserName pMprNotifyInfo->pszDomain pMprNotifyInfo->pszPassword pMprNotifyInfo->pszOldPassword