1078 lines
27 KiB
C++
1078 lines
27 KiB
C++
/***********************************************************************
|
|
*
|
|
* Copyright (C) 2005-2006 Novell, Inc. Inc. All Rights Reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; version 2.1
|
|
* of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, Novell, Inc.
|
|
*
|
|
* To contact Novell about this file by physical or electronic mail,
|
|
* you may find current contact information at www.novell.com.
|
|
*
|
|
***********************************************************************/
|
|
|
|
|
|
/***********************************************************************
|
|
* Following are registry entries, which must be created in order
|
|
* to run this credential manager;
|
|
*
|
|
* [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\NetworkProvider\Order
|
|
* "ProviderOrder"=LCredMgr,(original string)
|
|
* [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LCredMgr\networkprovider
|
|
* "Class"=dword:00000002
|
|
* "Name"="LoginCapture Credential Provider"
|
|
* "ProviderPath"="
|
|
*
|
|
* Following are registry entries, which must be created in order
|
|
* to run this notification dll;
|
|
*
|
|
* [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\LCredMgr]
|
|
* "Asynchronous"=dword:00000001
|
|
* "DLLName"="LCredMgr.dll"
|
|
* "Impersonate"=dword:00000001
|
|
* "Logoff"="NPLogoff"
|
|
*
|
|
***********************************************************************/
|
|
|
|
#include "lcredmgr.h"
|
|
#include <stdio.h>
|
|
|
|
//===[ External data ]=====================================================
|
|
|
|
//===[ Manifest constants ]================================================
|
|
|
|
//
|
|
// The authentication type is only used here in a Unicode context
|
|
//
|
|
#define MSV1_0_AUTH_TYPE L"MSV1_0:Interactive"
|
|
#define KERB_AUTH_TYPE L"Kerberos:Interactive"
|
|
#define WNNC_CRED_MANAGER 0xFFFF0000
|
|
|
|
#define WINDOWS_LOGON_ID 1
|
|
|
|
//===[ Type definitions ]==================================================
|
|
|
|
//===[ Function prototypes ]===============================================
|
|
|
|
BOOL WriteLogFile(LPTSTR String);
|
|
|
|
DWORD
|
|
APIENTRY
|
|
NPGetCaps (
|
|
DWORD ndex
|
|
);
|
|
|
|
DWORD
|
|
APIENTRY
|
|
NPLogonNotify (
|
|
PLUID lpLogonId,
|
|
LPCWSTR lpAuthentInfoType,
|
|
LPVOID lpAuthentInfo,
|
|
LPCWSTR lpPreviousAuthentInfoType,
|
|
LPVOID lpPreviousAuthentInfo,
|
|
LPWSTR lpStationName,
|
|
LPVOID StationHandle,
|
|
LPWSTR *lpLogonScript
|
|
);
|
|
|
|
DWORD
|
|
APIENTRY
|
|
NPPasswordChangeNotify (
|
|
LPCWSTR lpAuthentInfoType,
|
|
LPVOID lpAuthentInfo,
|
|
LPCWSTR lpPreviousAuthentInfoType,
|
|
LPVOID lpPreviousAuthentInfo,
|
|
LPWSTR lpStationName,
|
|
LPVOID StationHandle,
|
|
DWORD dwChangeInfo
|
|
);
|
|
|
|
//===[ Global variables ]==================================================
|
|
|
|
HMODULE g_hModule;
|
|
HANDLE g_hModuleMutex = NULL;
|
|
BOOLEAN g_bLibraryLoaded = FALSE;
|
|
|
|
HINSTANCE g_hCASALibrary;
|
|
|
|
PSETCREDENTIAL pCASASetCredential;
|
|
POPENCACHE pCASAOpenCache;
|
|
PCLOSECACHE pCASACloseCache;
|
|
|
|
#ifdef _DEBUG
|
|
|
|
void
|
|
DebugPrint
|
|
(
|
|
char *format,
|
|
...
|
|
)
|
|
{
|
|
va_list parameters; /* Pointer to parameters on the stack */
|
|
char newString[600] = {"=> LCredMgr: "};
|
|
/*
|
|
Get a pointer to the parameters
|
|
*/
|
|
va_start(parameters, format);
|
|
vsprintf( &newString[13], format, parameters );
|
|
OutputDebugStringA(newString);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
//++=======================================================================
|
|
BOOL
|
|
APIENTRY
|
|
DllMain (
|
|
HANDLE hInst,
|
|
DWORD dwReason,
|
|
LPVOID lpReserved
|
|
)
|
|
//=======================================================================--
|
|
{
|
|
|
|
#ifdef _DEBUG
|
|
DebugPrint("DllMain called.\n");
|
|
#endif
|
|
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
DisableThreadLibraryCalls((HINSTANCE)hInst);
|
|
|
|
g_hModule = (HMODULE)hInst;
|
|
|
|
g_hModuleMutex = CreateMutex(NULL, FALSE, NULL);
|
|
|
|
if (g_hModuleMutex == NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
InitLoginExtension();
|
|
|
|
//
|
|
// Always succeed, this allows us to be configured with regsvr32.exe
|
|
//
|
|
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
CloseHandle(g_hModuleMutex);
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//++=======================================================================
|
|
DWORD
|
|
WINAPI
|
|
NPGetCaps (
|
|
DWORD nIndex
|
|
)
|
|
//
|
|
// PURPOSE: This entry point is called to query the provider. The parameter
|
|
// is an index representing the query. For a credential manager
|
|
// only the following index values apply:
|
|
//
|
|
// WNNC_SPEC_VERSION - What version of the provider specification
|
|
// was used in developing this provider? The return value is
|
|
// the version number.
|
|
//
|
|
// WNNC_DRIVER_VERSION - The version of the provider.
|
|
//
|
|
// WNNC_START - Will the provider start? When? The return values
|
|
// are:
|
|
//
|
|
// - 0 : Only return this if the provider will *not* start.
|
|
// - Estimated Start time in milliseconds : This is how
|
|
// long the provider is expected to take to start.
|
|
// - 0xFFFFFFFF : Time to start is unknown.
|
|
// - 1 : Provider is already started.
|
|
//
|
|
// A return value of 0 in other cases indicates that the query
|
|
// is not supported.
|
|
//=======================================================================--
|
|
{
|
|
DWORD dwRes;
|
|
|
|
#ifdef _DEBUG
|
|
DebugPrint("NPGetCaps called with nIndex %u.\n", nIndex);
|
|
#endif
|
|
|
|
switch (nIndex)
|
|
{
|
|
case WNNC_NET_TYPE:
|
|
dwRes = WNNC_CRED_MANAGER;
|
|
break;
|
|
|
|
case WNNC_SPEC_VERSION:
|
|
dwRes = WNNC_SPEC_VERSION51; // We are using version 5.1 of the spec.
|
|
break;
|
|
|
|
case WNNC_DRIVER_VERSION:
|
|
dwRes = 1; // This driver is version 1.
|
|
break;
|
|
|
|
case WNNC_START:
|
|
dwRes = 1; // We are already "started"
|
|
break;
|
|
|
|
default:
|
|
dwRes = 0; // We don't support anything else
|
|
break;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
DebugPrint("NPGetCaps returning dwRes %u.\n", dwRes);
|
|
#endif
|
|
|
|
return dwRes;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
BOOLEAN
|
|
InitCASALibrary (
|
|
)
|
|
//
|
|
// PURPOSE: Loads the micasa dll entry points.
|
|
//=======================================================================--
|
|
{
|
|
BOOLEAN bLibraryLoaded = TRUE;
|
|
|
|
if (g_bLibraryLoaded == FALSE)
|
|
{
|
|
WaitForSingleObjectEx(g_hModuleMutex, INFINITE, FALSE);
|
|
bLibraryLoaded = FALSE;
|
|
|
|
if (g_bLibraryLoaded == FALSE)
|
|
{
|
|
g_hCASALibrary = LoadLibrary(L"micasa.dll");
|
|
|
|
if (g_hCASALibrary)
|
|
{
|
|
pCASASetCredential = (PSETCREDENTIAL)GetProcAddress(g_hCASALibrary, "miCASASetCredential");
|
|
pCASAOpenCache = (POPENCACHE)GetProcAddress(g_hCASALibrary, "miCASAOpenSecretStoreCache");
|
|
pCASACloseCache = (PCLOSECACHE)GetProcAddress(g_hCASALibrary, "miCASACloseSecretStoreCache");
|
|
|
|
bLibraryLoaded = TRUE;
|
|
g_bLibraryLoaded = TRUE;
|
|
}
|
|
#ifdef _DEBUG
|
|
else
|
|
{
|
|
DebugPrint("LoadLibrary for micasa.dll failed. %d\n", GetLastError());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
ReleaseMutex(g_hModuleMutex);
|
|
}
|
|
|
|
return bLibraryLoaded;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
DWORD
|
|
WINAPI
|
|
NPLogonNotify (
|
|
PLUID lpLogonId,
|
|
LPCWSTR lpAuthentInfoType,
|
|
LPVOID lpAuthentInfo,
|
|
LPCWSTR lpPreviousAuthentInfoType,
|
|
LPVOID lpPreviousAuthentInfo,
|
|
LPWSTR lpStationName,
|
|
LPVOID StationHandle,
|
|
LPWSTR *lpLogonScript
|
|
)
|
|
//
|
|
// PURPOSE: This entry point is called when a user logs on. If the user
|
|
// authentication fails here, the user will still be logged on
|
|
// to the local machine.
|
|
//=======================================================================--
|
|
{
|
|
int ccode;
|
|
PMSV1_0_INTERACTIVE_LOGON pAuthInfo;
|
|
SSCS_BASIC_CREDENTIAL basicCredential;
|
|
SSCS_SECRET_ID_T desktopCredential;
|
|
SSCS_SECRET_ID_T domainCredential;
|
|
SSCS_EXT_T extension;
|
|
BOOLEAN bLibraryLoaded;
|
|
|
|
#ifdef _DEBUG
|
|
DebugPrint("NPLogonNotify called.\n");
|
|
#endif
|
|
|
|
SetLastError(NO_ERROR);
|
|
|
|
bLibraryLoaded = InitCASALibrary();
|
|
|
|
if (bLibraryLoaded == FALSE)
|
|
{
|
|
SetLastError(NO_ERROR);
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// If the primary authenticator is not MSV1_0, return success.
|
|
// Why? Because this is the only auth info structure that we
|
|
// understand and we don't want to interact with other types.
|
|
//
|
|
|
|
if (!lstrcmpiW (MSV1_0_AUTH_TYPE, lpAuthentInfoType))
|
|
{
|
|
#ifdef _DEBUG
|
|
DebugPrint("NPLogonNotify auth type is MSV1_0_AUTH_TYPE.\n");
|
|
#endif
|
|
}
|
|
else if (!lstrcmpiW (KERB_AUTH_TYPE, lpAuthentInfoType))
|
|
{
|
|
#ifdef _DEBUG
|
|
DebugPrint("NPLogonNotify auth type is KERB_AUTH_TYPE.\n");
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#ifdef _DEBUG
|
|
DebugPrint("NPLogonNotify auth type is UNSUPPORTED.\n");
|
|
#endif
|
|
|
|
SetLastError(NO_ERROR);
|
|
return NO_ERROR;
|
|
}
|
|
|
|
if ((wcscmp(L"SvcCtl", lpStationName)) == 0)
|
|
{
|
|
#ifdef _DEBUG
|
|
DebugPrint("NPLogonNotify stationname indicates a service has logged on.\n");
|
|
#endif
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Do something with the authentication information
|
|
//
|
|
|
|
pAuthInfo = (PMSV1_0_INTERACTIVE_LOGON) lpAuthentInfo;
|
|
|
|
basicCredential.unLen = WideCharToMultiByte(
|
|
CP_UTF8,
|
|
0,
|
|
pAuthInfo->UserName.Buffer,
|
|
-1,
|
|
(LPSTR)&basicCredential.username,
|
|
NSSCS_MAX_USERID_LEN,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (basicCredential.unLen)
|
|
{
|
|
// basicCredential.unLen++;
|
|
|
|
basicCredential.pwordLen = WideCharToMultiByte(
|
|
CP_UTF8,
|
|
0,
|
|
pAuthInfo->Password.Buffer,
|
|
-1,
|
|
(LPSTR)&basicCredential.password,
|
|
NSSCS_MAX_PWORD_LEN,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (basicCredential.pwordLen)
|
|
{
|
|
// basicCredential.pwordLen++;
|
|
|
|
strcpy((char *)&desktopCredential.id, "Desktop");
|
|
desktopCredential.len = (long)strlen((char *)&desktopCredential.id) + 1;
|
|
|
|
basicCredential.unFlags = USERNAME_TYPE_CN_F;
|
|
|
|
extension.extID = WINDOWS_LOGON_ID;
|
|
extension.version = 0x00010000; // 1.0.0
|
|
extension.ext = (void *)lpLogonId;
|
|
|
|
ccode = (*pCASASetCredential)(
|
|
0,
|
|
&desktopCredential,
|
|
NULL,
|
|
SSCS_CRED_TYPE_BASIC_F,
|
|
&basicCredential,
|
|
&extension);
|
|
|
|
#ifdef _DEBUG
|
|
if (!ccode)
|
|
{
|
|
DebugPrint("NSSCSSetCredential successful!.\n");
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("NSSCSSetCredential failed 0x%X\n", ccode);
|
|
}
|
|
#endif
|
|
|
|
if (pAuthInfo->LogonDomainName.Length != 0)
|
|
{
|
|
domainCredential.len = WideCharToMultiByte(
|
|
CP_UTF8,
|
|
0,
|
|
pAuthInfo->LogonDomainName.Buffer,
|
|
-1,
|
|
(LPSTR)&domainCredential.id,
|
|
NSSCS_MAX_SECRET_ID_LEN,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (domainCredential.len)
|
|
{
|
|
// domainCredential.len++;
|
|
|
|
#ifdef _DEBUG
|
|
DebugPrint("Domain exists - [%s], length %d\n", domainCredential.id, domainCredential.len);
|
|
#endif
|
|
|
|
ccode = (*pCASASetCredential)(
|
|
0,
|
|
&desktopCredential,
|
|
&domainCredential,
|
|
SSCS_CRED_TYPE_BASIC_F,
|
|
&basicCredential,
|
|
&extension);
|
|
|
|
#ifdef _DEBUG
|
|
if (!ccode)
|
|
{
|
|
DebugPrint("NSSCSSetCredential successful!.\n");
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("NSSCSSetCredential failed 0x%X\n", ccode);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
}
|
|
}
|
|
#ifdef _DEBUG
|
|
else
|
|
{
|
|
DebugPrint("WideCharToMultiByte for password failed.\n");
|
|
}
|
|
#endif
|
|
}
|
|
#ifdef _DEBUG
|
|
else
|
|
{
|
|
DebugPrint("WideCharToMultiByte for user name failed.\n");
|
|
}
|
|
#endif
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//++=======================================================================
|
|
DWORD
|
|
WINAPI
|
|
NPPasswordChangeNotify (
|
|
LPCWSTR lpAuthentInfoType,
|
|
LPVOID lpAuthentInfo,
|
|
LPCWSTR lpPreviousAuthentInfoType,
|
|
LPVOID lpPreviousAuthentInfo,
|
|
LPWSTR lpStationName,
|
|
LPVOID StationHandle,
|
|
DWORD dwChangeInfo
|
|
)
|
|
//
|
|
// PURPOSE: This function is used to notify a credential manager provider
|
|
// of a password change (or, more accurately, an authentication
|
|
// information change) for an account.
|
|
//=======================================================================--
|
|
{
|
|
// return NO_ERROR;
|
|
#ifdef _DEBUG
|
|
DebugPrint("NPPasswordChangeNotify called.\n");
|
|
#endif
|
|
return WN_NOT_SUPPORTED;
|
|
}
|
|
|
|
//++=======================================================================
|
|
VOID
|
|
WINAPI
|
|
NPLogoff(
|
|
PWLX_NOTIFICATION_INFO pInfo
|
|
)
|
|
//=======================================================================--
|
|
{
|
|
DWORD dwSize;
|
|
TOKEN_STATISTICS tokenStats;
|
|
SSCS_SECRETSTORE_T ssId;
|
|
HANDLE context;
|
|
BOOLEAN bLibraryLoaded;
|
|
|
|
#ifdef _DEBUG
|
|
DebugPrint("NPLogoff called.\n");
|
|
#endif
|
|
|
|
dwSize = sizeof(tokenStats);
|
|
|
|
if (GetTokenInformation(
|
|
pInfo->hToken,
|
|
TokenStatistics,
|
|
&tokenStats,
|
|
dwSize,
|
|
&dwSize))
|
|
{
|
|
#ifdef _DEBUG
|
|
DebugPrint("GetTokenInformation for statistics returned LowPart 0x%X HighPart 0x%X\n", tokenStats.AuthenticationId.LowPart, tokenStats.AuthenticationId.HighPart);
|
|
#endif
|
|
|
|
|
|
}
|
|
#ifdef _DEBUG
|
|
else
|
|
{
|
|
DebugPrint("GetTokenInformation for TokenStatistics failed %u\n", GetLastError());
|
|
}
|
|
#endif
|
|
|
|
bLibraryLoaded = TRUE;
|
|
WaitForSingleObjectEx(g_hModuleMutex, INFINITE, FALSE);
|
|
|
|
if (g_bLibraryLoaded == FALSE)
|
|
{
|
|
#ifdef _DEBUG
|
|
DebugPrint("Library not loaded in NPLogoff.\n");
|
|
#endif
|
|
bLibraryLoaded = FALSE;
|
|
}
|
|
|
|
ReleaseMutex(g_hModuleMutex);
|
|
|
|
if (bLibraryLoaded == FALSE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ssId.version = NSSCS_VERSION_NUMBER;
|
|
strcpy((char *)ssId.ssName, (char *)SSCS_DEFAULT_SECRETSTORE_ID);
|
|
|
|
context = (*pCASAOpenCache)(
|
|
&ssId,
|
|
0,
|
|
NULL);
|
|
|
|
if (context)
|
|
{
|
|
//
|
|
// the SSFLAG_DESTROY_SESSION_F closes the session for this user
|
|
//
|
|
|
|
(*pCASACloseCache)(
|
|
context,
|
|
SSFLAG_DESTROY_SESSION_F,
|
|
NULL);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//++=======================================================================
|
|
DWORD
|
|
AddSubString(
|
|
HKEY hKey
|
|
)
|
|
//=======================================================================--
|
|
{
|
|
LONG rc;
|
|
CHAR szValue[256],
|
|
szNewValue[256];
|
|
DWORD valueSize;
|
|
|
|
|
|
valueSize = sizeof(szValue);
|
|
|
|
rc = RegQueryValueExA(
|
|
hKey,
|
|
"ProviderOrder",
|
|
0,
|
|
NULL,
|
|
(PUCHAR)szValue,
|
|
&valueSize);
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
strcpy (szNewValue, "LCredMgr,");
|
|
strcat (szNewValue, szValue);
|
|
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"ProviderOrder",
|
|
0,
|
|
REG_SZ,
|
|
(PUCHAR)szNewValue,
|
|
(DWORD) strlen(szNewValue));
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
//++=======================================================================
|
|
DWORD
|
|
RemoveSubString(
|
|
HKEY hKey
|
|
)
|
|
//=======================================================================--
|
|
{
|
|
LONG rc;
|
|
CHAR szValue[256],
|
|
szNewValue[256];
|
|
PCHAR subString, startString, endString;
|
|
DWORD valueSize;
|
|
|
|
|
|
valueSize = sizeof(szValue);
|
|
|
|
rc = RegQueryValueExA(
|
|
hKey,
|
|
"ProviderOrder",
|
|
0,
|
|
NULL,
|
|
(PUCHAR)szValue,
|
|
&valueSize);
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
//
|
|
// Remove any leading whitespace
|
|
//
|
|
|
|
subString = szValue;
|
|
|
|
while (*subString != NULL && (*subString == ',' || *subString == ' '))
|
|
{
|
|
subString++;
|
|
}
|
|
|
|
startString = subString;
|
|
|
|
//
|
|
// Check to see if lcredmgr is in the string
|
|
//
|
|
|
|
if ((subString = strstr(startString, "LCredMgr")) != NULL)
|
|
{
|
|
if (subString == startString)
|
|
{
|
|
while (*subString != ',' && *subString != NULL)
|
|
{
|
|
subString++;
|
|
}
|
|
|
|
while ((*subString == ',' || *subString == ' ') && *subString != NULL)
|
|
{
|
|
subString++;
|
|
}
|
|
|
|
startString = subString;
|
|
}
|
|
else
|
|
{
|
|
endString = subString + 8;
|
|
|
|
//
|
|
// Back up past any whitespace or comma's.
|
|
//
|
|
|
|
for (subString--;;subString--)
|
|
{
|
|
if (*subString != ' ' && *subString != ',')
|
|
{
|
|
*(subString + 1) = '\0';
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Get past any comma's
|
|
//
|
|
|
|
for (;;endString++)
|
|
{
|
|
if (*endString == NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ((*endString != ',' && *endString != ' '))
|
|
{
|
|
//
|
|
// concat the two strings without lcredmgr
|
|
//
|
|
|
|
strcpy (szNewValue, startString);
|
|
strcat (szNewValue, endString);
|
|
startString = szNewValue;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"ProviderOrder",
|
|
0,
|
|
REG_SZ,
|
|
(PUCHAR)startString,
|
|
(DWORD) strlen(startString));
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
//++=======================================================================
|
|
HRESULT
|
|
DllInstall(
|
|
BOOL bInstall,
|
|
LPCWSTR pszCmdLine
|
|
)
|
|
//=======================================================================--
|
|
{
|
|
HKEY hKey;
|
|
LONG rc;
|
|
CHAR szModule[256];
|
|
DWORD value, valueSize;
|
|
|
|
#ifdef _DEBUG
|
|
DebugPrint("DllInstall called\n");
|
|
OutputDebugStringW(pszCmdLine);
|
|
#endif
|
|
|
|
|
|
if (bInstall == TRUE)
|
|
{
|
|
rc = RegCreateKeyExA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"System\\CurrentControlSet\\Control\\NetworkProvider\\Order",
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
NULL);
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
rc = RemoveSubString(hKey);
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
rc = AddSubString(hKey);
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
//
|
|
// Set up our service key
|
|
//
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
rc = RegCreateKeyExA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"System\\CurrentControlSet\\Services\\LCredMgr\\networkprovider",
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
NULL);
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
value = 2;
|
|
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"Class",
|
|
0,
|
|
REG_DWORD,
|
|
(BYTE *)&value,
|
|
sizeof(value));
|
|
|
|
if (rc != S_OK)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"Name",
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)"LoginCapture Credential Provider",
|
|
32);
|
|
|
|
if (rc != S_OK)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
valueSize = GetModuleFileNameA((HMODULE)g_hModule, szModule, sizeof(szModule));
|
|
|
|
if (valueSize)
|
|
{
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"ProviderPath",
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)szModule,
|
|
valueSize + 1);
|
|
}
|
|
else
|
|
{
|
|
rc = GetLastError();
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
rc = RegCreateKeyExA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify\\LCredMgr",
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
NULL);
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
value = 1;
|
|
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"Asynchronous",
|
|
0,
|
|
REG_DWORD,
|
|
(BYTE *)&value,
|
|
sizeof(value));
|
|
|
|
if (rc != S_OK)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"DLLName",
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)szModule,
|
|
valueSize + 1);
|
|
|
|
if (rc != S_OK)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"Impersonate",
|
|
0,
|
|
REG_DWORD,
|
|
(BYTE *)&value,
|
|
sizeof(value));
|
|
|
|
if (rc != S_OK)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"Logoff",
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)"NPLogoff",
|
|
9);
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
rc = RegCreateKeyExA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"SOFTWARE\\Novell\\Graphical Login\\NWLGE\\LCredMgr",
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
NULL);
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"LoginExtName",
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)szModule,
|
|
valueSize + 1);
|
|
|
|
if (rc != S_OK)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"LoginExtDesc",
|
|
0,
|
|
REG_SZ,
|
|
(BYTE *)"CASA Login Extension",
|
|
20);
|
|
|
|
if (rc != S_OK)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
value = 0x00008002;
|
|
|
|
rc = RegSetValueExA(
|
|
hKey,
|
|
"LoginExtType",
|
|
0,
|
|
REG_DWORD,
|
|
(BYTE *)&value,
|
|
sizeof(value));
|
|
|
|
ErrorExit:
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = RegCreateKeyExA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"System\\CurrentControlSet\\Control\\NetworkProvider\\Order",
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hKey,
|
|
NULL);
|
|
|
|
if (rc == S_OK)
|
|
{
|
|
RemoveSubString(hKey);
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
//
|
|
// Delete our service key
|
|
//
|
|
|
|
RegDeleteKeyA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"System\\CurrentControlSet\\Services\\LCredMgr\\Enum");
|
|
|
|
RegDeleteKeyA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"System\\CurrentControlSet\\Services\\LCredMgr\\networkprovider");
|
|
|
|
RegDeleteKeyA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"System\\CurrentControlSet\\Services\\LCredMgr");
|
|
|
|
RegDeleteKeyA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify\\LCredMgr");
|
|
|
|
RegDeleteKeyA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"SOFTWARE\\Novell\\Graphical Login\\NWLGE\\LCredMgr");
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
if (rc == S_OK)
|
|
{
|
|
DebugPrint("DllInstall successful.\n");
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("DllInstall failed.\n");
|
|
}
|
|
#endif
|
|
|
|
return rc;
|
|
}
|
|
|
|
//++=======================================================================
|
|
STDAPI
|
|
DllRegisterServer(
|
|
void
|
|
)
|
|
//=======================================================================--
|
|
{
|
|
#ifdef _DEBUG
|
|
DebugPrint("DllRegisterServer called\n");
|
|
#endif
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//++=======================================================================
|
|
STDAPI
|
|
DllUnregisterServer(
|
|
void
|
|
)
|
|
//=======================================================================--
|
|
{
|
|
#ifdef _DEBUG
|
|
DebugPrint("DllUnregisterServer called\n");
|
|
#endif
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//=========================================================================
|
|
//=========================================================================
|
|
|