mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1045 lines
27 KiB
1045 lines
27 KiB
/****************************** Module Header ******************************\
|
|
* Module Name: provider.c
|
|
*
|
|
* Copyright (c) 1991, Microsoft Corporation
|
|
*
|
|
* Implements functions that support multiple network providers.
|
|
* Currently this involves notifying credential managers of logon and
|
|
* password change operations.
|
|
*
|
|
* History:
|
|
* 01-10-93 Davidc Created.
|
|
\***************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// Define this to enable verbose output for this module
|
|
//
|
|
|
|
// #define DEBUG_PROVIDER
|
|
|
|
#ifdef DEBUG_PROVIDER
|
|
#define VerbosePrint(s) WLPrint(s)
|
|
#else
|
|
#define VerbosePrint(s)
|
|
#endif
|
|
|
|
|
|
//
|
|
// Define the key in the winlogon section of win.ini that
|
|
// defines the the multiple provider notify app name.
|
|
//
|
|
|
|
#define NOTIFY_KEY_NAME TEXT("mpnotify")
|
|
|
|
//
|
|
// Define the default multiple provider notify app name.
|
|
//
|
|
|
|
#define DEFAULT_NOTIFY_APP_NAME TEXT("mpnotify.exe")
|
|
|
|
|
|
//
|
|
// Define environment variables used to pass information to multiple
|
|
// provider notify process
|
|
//
|
|
|
|
#define MPR_STATION_NAME_VARIABLE TEXT("WlMprNotifyStationName")
|
|
#define MPR_STATION_HANDLE_VARIABLE TEXT("WlMprNotifyStationHandle")
|
|
#define MPR_WINLOGON_WINDOW_VARIABLE TEXT("WlMprNotifyWinlogonWindow")
|
|
|
|
#define MPR_LOGON_FLAG_VARIABLE TEXT("WlMprNotifyLogonFlag")
|
|
#define MPR_USERNAME_VARIABLE TEXT("WlMprNotifyUserName")
|
|
#define MPR_DOMAIN_VARIABLE TEXT("WlMprNotifyDomain")
|
|
#define MPR_PASSWORD_VARIABLE TEXT("WlMprNotifyPassword")
|
|
#define MPR_OLD_PASSWORD_VARIABLE TEXT("WlMprNotifyOldPassword")
|
|
#define MPR_OLD_PASSWORD_VALID_VARIABLE TEXT("WlMprNotifyOldPasswordValid")
|
|
#define MPR_LOGONID_VARIABLE TEXT("WlMprNotifyLogonId")
|
|
#define MPR_CHANGE_INFO_VARIABLE TEXT("WlMprNotifyChangeInfo")
|
|
#define MPR_PASSTHROUGH_VARIABLE TEXT("WlMprNotifyPassThrough")
|
|
#define MPR_PROVIDER_VARIABLE TEXT("WlMprNotifyProvider")
|
|
|
|
|
|
// Message we send to ourselves so we can hide.
|
|
#define WM_HIDEOURSELVES (WM_USER + 0)
|
|
|
|
|
|
|
|
//
|
|
// Define the structure used to pass data into the notify control dialog
|
|
//
|
|
|
|
typedef struct {
|
|
PGLOBALS pGlobals;
|
|
LPWSTR ReturnBuffer; // Returned from dialog
|
|
HANDLE hProcess;
|
|
POBJECT_MONITOR Monitor;
|
|
BOOL ProcessRunning;
|
|
} NOTIFY_DATA;
|
|
typedef NOTIFY_DATA *PNOTIFY_DATA;
|
|
|
|
|
|
|
|
|
|
//
|
|
// Private prototypes
|
|
//
|
|
|
|
BOOL
|
|
MprNotifyDlgInit(
|
|
HWND hDlg
|
|
);
|
|
|
|
BOOL
|
|
StartNotifyProcessMonitor(
|
|
HWND hDlg
|
|
);
|
|
|
|
VOID
|
|
DeleteNotifyProcessMonitor(
|
|
HWND hDlg
|
|
);
|
|
|
|
BOOL
|
|
KillNotifyProcess(
|
|
PNOTIFY_DATA pNotifyData
|
|
);
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: DeleteNotifyVariables
|
|
*
|
|
* PURPOSE: Deletes all the notify data environment variables from the
|
|
* current process's environment.
|
|
*
|
|
* RETURNS: Nothing
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-12-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
VOID
|
|
DeleteNotifyVariables(
|
|
VOID
|
|
)
|
|
{
|
|
SetEnvironmentVariable(MPR_STATION_NAME_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_STATION_HANDLE_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_WINLOGON_WINDOW_VARIABLE, NULL);
|
|
|
|
SetEnvironmentVariable(MPR_LOGON_FLAG_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_USERNAME_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_DOMAIN_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_PASSWORD_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_OLD_PASSWORD_VALID_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_OLD_PASSWORD_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_LOGONID_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_CHANGE_INFO_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_PASSTHROUGH_VARIABLE, NULL);
|
|
SetEnvironmentVariable(MPR_PROVIDER_VARIABLE, NULL);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: SetWinlogonWindowVariable
|
|
*
|
|
* PURPOSE: Sets winlogon window environment variable in current process's
|
|
* environment - this is inherited by notify process.
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-12-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
SetWinlogonWindowVariable(
|
|
HWND hwnd
|
|
)
|
|
{
|
|
BOOL Result;
|
|
|
|
Result = SetEnvironmentULong(MPR_WINLOGON_WINDOW_VARIABLE, (ULONG)hwnd);
|
|
|
|
if (!Result) {
|
|
DebugLog((DEB_ERROR, "SetWinlogonWindowVariable: Failed to set variable, error = %d\n", GetLastError()));
|
|
}
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: SetCommonNotifyVariables
|
|
*
|
|
* PURPOSE: Sets environment variables to pass information to notify process
|
|
* for data that is common to all notifications.
|
|
* The variables are set in winlogon's environment - this is
|
|
* inherited by the notify process.
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* On failure return, all notify variables have been deleted
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-12-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
SetCommonNotifyVariables(
|
|
PGLOBALS pGlobals,
|
|
HWND hwndOwner,
|
|
LPTSTR Name OPTIONAL,
|
|
LPTSTR Domain OPTIONAL,
|
|
LPTSTR Password OPTIONAL,
|
|
LPTSTR OldPassword OPTIONAL
|
|
)
|
|
{
|
|
BOOL Result = TRUE;
|
|
|
|
if (Result) {
|
|
Result = SetEnvironmentVariable(MPR_STATION_NAME_VARIABLE, WINDOW_STATION_NAME);
|
|
}
|
|
if (Result) {
|
|
Result = SetEnvironmentULong(MPR_STATION_HANDLE_VARIABLE, (ULONG)hwndOwner);
|
|
}
|
|
|
|
if (Result && ARGUMENT_PRESENT( Name )) {
|
|
Result = SetEnvironmentVariable(MPR_USERNAME_VARIABLE, Name);
|
|
}
|
|
if (Result && ARGUMENT_PRESENT( Domain )) {
|
|
Result = SetEnvironmentVariable(MPR_DOMAIN_VARIABLE, Domain);
|
|
}
|
|
if (Result && ARGUMENT_PRESENT( Password )) {
|
|
Result = SetEnvironmentVariable(MPR_PASSWORD_VARIABLE, Password);
|
|
}
|
|
if (Result) {
|
|
Result = SetEnvironmentULong(MPR_OLD_PASSWORD_VALID_VARIABLE,
|
|
(OldPassword != NULL) ? 1 : 0);
|
|
}
|
|
if (Result) {
|
|
Result = SetEnvironmentVariable(MPR_OLD_PASSWORD_VARIABLE, OldPassword);
|
|
if (OldPassword == NULL) {
|
|
Result = TRUE; // Ignore failure since deleting a variable that
|
|
// doesn't exist returns failure.
|
|
}
|
|
}
|
|
|
|
if (!Result) {
|
|
DebugLog((DEB_ERROR, "SetCommonNotifyVariables: Failed to set a variable, error = %d\n", GetLastError()));
|
|
DeleteNotifyVariables();
|
|
}
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: SetLogonNotifyVariables
|
|
*
|
|
* PURPOSE: Sets environment variables to pass information to notify process
|
|
* for data that is specific to logon notifications.
|
|
* The variables are set in winlogon's environment - this is
|
|
* inherited by the notify process.
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* On failure return, all notify variables have been deleted
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-12-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
SetLogonNotifyVariables(
|
|
PLUID LogonId
|
|
)
|
|
{
|
|
BOOL Result;
|
|
LARGE_INTEGER LargeInt;
|
|
|
|
LargeInt.LowPart = LogonId->LowPart;
|
|
LargeInt.HighPart = LogonId->HighPart;
|
|
Result = SetEnvironmentLargeInt(MPR_LOGONID_VARIABLE, LargeInt);
|
|
if (Result) {
|
|
Result = SetEnvironmentULong(MPR_LOGON_FLAG_VARIABLE, 1);
|
|
}
|
|
|
|
if (!Result) {
|
|
DebugLog((DEB_ERROR, "SetLogonNotifyVariables: Failed to set variable, error = %d\n", GetLastError()));
|
|
DeleteNotifyVariables();
|
|
}
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: SetChangePasswordNotifyVariables
|
|
*
|
|
* PURPOSE: Sets environment variables to pass information to notify process
|
|
* for data that is specific to change password notifications.
|
|
* The variables are set in winlogon's environment - this is
|
|
* inherited by the notify process.
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* On failure return, all notify variables have been deleted
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-12-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
SetChangePasswordNotifyVariables(
|
|
DWORD ChangeInfo,
|
|
BOOL PassThrough,
|
|
PWSTR Provider OPTIONAL
|
|
)
|
|
{
|
|
BOOL Result;
|
|
|
|
Result = SetEnvironmentULong(MPR_CHANGE_INFO_VARIABLE, ChangeInfo);
|
|
if (Result) {
|
|
Result = SetEnvironmentULong(MPR_LOGON_FLAG_VARIABLE, 0);
|
|
}
|
|
|
|
if (Result) {
|
|
Result = SetEnvironmentULong(MPR_PASSTHROUGH_VARIABLE, (PassThrough ? 1 : 0));
|
|
}
|
|
|
|
if (Result && ARGUMENT_PRESENT( Provider ) )
|
|
{
|
|
Result = SetEnvironmentVariable( MPR_PROVIDER_VARIABLE, Provider );
|
|
}
|
|
|
|
if (!Result) {
|
|
DebugLog((DEB_ERROR, "SetChangePasswordNotifyVariables: Failed to set variable, error = %d\n", GetLastError()));
|
|
DeleteNotifyVariables();
|
|
}
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: MprNotifyDlgProc
|
|
*
|
|
* PURPOSE: Processes messages for the Mpr Notify dialog
|
|
*
|
|
* RETURNS: DLG_SUCCESS - the notification went without a hitch
|
|
* - NotifyData->ReturnBuffer is valid.
|
|
* DLG_FAILURE - something failed or there is no buffer to return.
|
|
* - NotifyData->ReturnBuffer is invalid.
|
|
*
|
|
* DLG_INTERRUPTED() - a set defined in winlogon.h
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-11-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL WINAPI
|
|
MprNotifyDlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
PNOTIFY_DATA pNotifyData = (PNOTIFY_DATA)GetWindowLong(hDlg, GWL_USERDATA);
|
|
PCOPYDATASTRUCT CopyData;
|
|
|
|
switch (message) {
|
|
|
|
case WM_INITDIALOG:
|
|
SetWindowLong(hDlg, GWL_USERDATA, lParam);
|
|
|
|
if (!MprNotifyDlgInit(hDlg)) {
|
|
EndDialog(hDlg, DLG_FAILURE);
|
|
return(TRUE);
|
|
}
|
|
|
|
//
|
|
// Send ourselves a message so we can hide without the
|
|
// dialog code trying to force us to be visible
|
|
//
|
|
|
|
PostMessage(hDlg, WM_HIDEOURSELVES, 0, 0);
|
|
return(TRUE);
|
|
|
|
|
|
case WM_HIDEOURSELVES:
|
|
ShowWindow(hDlg, SW_HIDE);
|
|
return(TRUE);
|
|
|
|
|
|
case WLX_WM_SAS:
|
|
|
|
if (wParam == WLX_SAS_TYPE_USER_LOGOFF)
|
|
{
|
|
DebugLog((DEB_TRACE_MPR, "Got a logoff notification\n"));
|
|
}
|
|
//
|
|
// Interrupt the notify process
|
|
// This gives us a way to terminate the notify process if it hangs up.
|
|
//
|
|
|
|
DebugLog((DEB_TRACE_MPR, "Got SAS message - interrupting notify process\n"));
|
|
EndDialog(hDlg, DLG_FAILURE);
|
|
return(TRUE);
|
|
|
|
|
|
case WM_COPYDATA:
|
|
|
|
//
|
|
// The notify process completed and is passing us the result
|
|
//
|
|
|
|
CopyData = (PCOPYDATASTRUCT)lParam;
|
|
|
|
DebugLog((DEB_TRACE_MPR, "Got WM_COPYDATA message from notify process\n"));
|
|
DebugLog((DEB_TRACE_MPR, "/tdwData = %d", CopyData->dwData));
|
|
DebugLog((DEB_TRACE_MPR, "/tcbData = %d", CopyData->cbData));
|
|
|
|
//
|
|
// End the screen-saver if it's running
|
|
// This assumes the screen-saver dialog terminates when it gets SAS.
|
|
// If it's not running this will come straight to us which is OK
|
|
//
|
|
|
|
DebugLog((DEB_TRACE_MPR, "Forwarding SAS message to top window\n"));
|
|
//ForwardMessage(pNotifyData->pGlobals, WM_SAS, 0, 0);
|
|
|
|
|
|
//
|
|
// Copy the passed data and quit this dialog
|
|
//
|
|
|
|
if (CopyData->dwData == 0) {
|
|
if (CopyData->cbData != 0) {
|
|
pNotifyData->ReturnBuffer = Alloc(CopyData->cbData);
|
|
if (pNotifyData->ReturnBuffer != NULL) {
|
|
CopyMemory(pNotifyData->ReturnBuffer, CopyData->lpData, CopyData->cbData);
|
|
} else {
|
|
DebugLog((DEB_ERROR, ("Failed to allocate memory for returned logon scripts")));
|
|
}
|
|
} else {
|
|
pNotifyData->ReturnBuffer = NULL;
|
|
}
|
|
|
|
} else {
|
|
DebugLog((DEB_TRACE_MPR, "Notify completed with an error: %d", CopyData->dwData));
|
|
}
|
|
|
|
EndDialog(hDlg, pNotifyData->ReturnBuffer ? DLG_SUCCESS : DLG_FAILURE);
|
|
|
|
return(TRUE); // We processed this message
|
|
|
|
|
|
|
|
case WM_OBJECT_NOTIFY:
|
|
|
|
//
|
|
// The notify process terminated for some reason
|
|
//
|
|
|
|
DebugLog((DEB_TRACE_MPR, "Notify process terminated - got monitor notification\n"));
|
|
EndDialog(hDlg, DLG_FAILURE);
|
|
return(TRUE);
|
|
|
|
|
|
|
|
case WM_DESTROY:
|
|
|
|
//
|
|
// Terminate the notify process and delete the monitor object.
|
|
//
|
|
|
|
if (pNotifyData->ProcessRunning) {
|
|
|
|
DebugLog((DEB_TRACE_MPR, "NotifyDlgProc: Deleting notify process and monitor\n"));
|
|
|
|
DeleteNotifyProcessMonitor(hDlg);
|
|
KillNotifyProcess(pNotifyData);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
// We didn't process the message
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: MprNotifyDlgInit
|
|
*
|
|
* PURPOSE: Handles initialization of Mpr notify dialog
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-11-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
#if DEVL
|
|
BOOL bDebugMpNotify = FALSE;
|
|
#endif
|
|
|
|
BOOL
|
|
MprNotifyDlgInit(
|
|
HWND hDlg
|
|
)
|
|
{
|
|
PNOTIFY_DATA pNotifyData = (PNOTIFY_DATA)GetWindowLong(hDlg, GWL_USERDATA);
|
|
PGLOBALS pGlobals = pNotifyData->pGlobals;
|
|
USER_PROCESS_DATA SystemProcessData;
|
|
BOOL Success;
|
|
LPTSTR NotifyApp;
|
|
PROCESS_INFORMATION ProcessInformation;
|
|
PWSTR pchCmdLine;
|
|
#if DEVL
|
|
WCHAR chDebugCmdLine[ MAX_PATH ];
|
|
#endif
|
|
|
|
//
|
|
// Initialize flag to show we haven't created the notify process yet
|
|
//
|
|
|
|
pNotifyData->ProcessRunning = FALSE;
|
|
|
|
//
|
|
// Set our size to zero so we we don't appear
|
|
//
|
|
|
|
SetWindowPos(hDlg, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE |
|
|
SWP_NOREDRAW | SWP_NOZORDER);
|
|
|
|
//
|
|
// Set the winlogon window variable so the process knows who we are
|
|
//
|
|
|
|
SetWinlogonWindowVariable(hDlg);
|
|
|
|
//
|
|
// Start the notify process in system context
|
|
//
|
|
|
|
SystemProcessData.UserToken = NULL;
|
|
SystemProcessData.UserSid = pGlobals->WinlogonSid;
|
|
SystemProcessData.NewProcessSD = NULL;
|
|
SystemProcessData.NewProcessTokenSD = NULL;
|
|
SystemProcessData.NewThreadSD = NULL;
|
|
SystemProcessData.NewThreadTokenSD = NULL;
|
|
SystemProcessData.Quotas.PagedPoolLimit = 0;
|
|
SystemProcessData.CurrentDirectory = NULL;
|
|
SystemProcessData.pEnvironment = NULL; // Inherit our environment
|
|
|
|
//
|
|
// Get the name of the notify app
|
|
//
|
|
|
|
NotifyApp = AllocAndGetProfileString(WINLOGON, NOTIFY_KEY_NAME, DEFAULT_NOTIFY_APP_NAME);
|
|
if (NotifyApp == NULL) {
|
|
DebugLog((DEB_ERROR, "Failed to get name of provider notify app from registry\n"));
|
|
return(FALSE);
|
|
}
|
|
|
|
pchCmdLine = NotifyApp;
|
|
|
|
//
|
|
// Try and execute it
|
|
//
|
|
#if DEVL
|
|
if (bDebugMpNotify) {
|
|
wsprintf( chDebugCmdLine, TEXT("ntsd -d %s%s"),
|
|
bDebugMpNotify == 2 ? TEXT("-g -G ") : TEXT(""),
|
|
pchCmdLine
|
|
);
|
|
pchCmdLine = chDebugCmdLine;
|
|
}
|
|
#endif
|
|
|
|
|
|
Success = StartSystemProcess(pchCmdLine,
|
|
WINLOGON_DESKTOP_PATH,
|
|
0,
|
|
0,
|
|
NULL,
|
|
FALSE,
|
|
&pNotifyData->hProcess,
|
|
NULL);
|
|
|
|
Free(NotifyApp);
|
|
|
|
if (!Success) {
|
|
DebugLog((DEB_ERROR, "Failed to start multiple provider notifier\n"));
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Store the process id in our notify data for future reference
|
|
//
|
|
|
|
|
|
|
|
//
|
|
// Start the thread that will wait for the notify process to finish
|
|
//
|
|
|
|
if (!StartNotifyProcessMonitor(hDlg)) {
|
|
|
|
DebugLog((DEB_ERROR, "Failed to start notify process monitor thread\n"));
|
|
KillNotifyProcess(pNotifyData);
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Record the fact we started the notify process so we know
|
|
// to cleanup during WM_DESTROY
|
|
//
|
|
|
|
pNotifyData->ProcessRunning = TRUE;
|
|
|
|
// Success
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: StartNotifyProcessMonitor
|
|
*
|
|
* PURPOSE: Creates a thread that waits for the notify process to terminate
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-11-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
StartNotifyProcessMonitor(
|
|
HWND hDlg
|
|
)
|
|
{
|
|
PNOTIFY_DATA NotifyData = (PNOTIFY_DATA)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
NotifyData->Monitor = CreateObjectMonitor(NotifyData->hProcess, hDlg, 0);
|
|
|
|
if (NotifyData->Monitor == NULL) {
|
|
DebugLog((DEB_ERROR, "Failed to create notify process monitor object\n"));
|
|
return(FALSE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: DeleteNotifyProcessMonitor
|
|
*
|
|
* PURPOSE: Cleans up resources used by notify process monitor
|
|
*
|
|
* RETURNS: Nothing
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-11-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
VOID
|
|
DeleteNotifyProcessMonitor(
|
|
HWND hDlg
|
|
)
|
|
{
|
|
PNOTIFY_DATA NotifyData = (PNOTIFY_DATA)GetWindowLong(hDlg, GWL_USERDATA);
|
|
POBJECT_MONITOR Monitor = NotifyData->Monitor;
|
|
HANDLE ProcessHandle = GetObjectMonitorObject(Monitor);
|
|
|
|
//
|
|
// Delete the object monitor
|
|
//
|
|
|
|
DeleteObjectMonitor(Monitor, TRUE);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: KillNotifyProcess
|
|
*
|
|
* PURPOSE: Terminates the notify process
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-11-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
KillNotifyProcess(
|
|
PNOTIFY_DATA NotifyData
|
|
)
|
|
{
|
|
|
|
if (!TerminateProcess(NotifyData->hProcess, STATUS_SUCCESS)) {
|
|
DebugLog((DEB_ERROR, "Failed to terminate notification process, error = %d\n", GetLastError()));
|
|
return(FALSE);
|
|
}
|
|
|
|
CloseHandle(NotifyData->hProcess);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: NoNeedToNotify
|
|
*
|
|
* PURPOSE: Determines if it is necessary to call the notify apis.
|
|
* It is not necessary if there is only one provider installed.
|
|
*
|
|
* We use this to save time in the common case where there is
|
|
* only one provider. We can avoid the overhead of creating
|
|
* the notify process in this case.
|
|
*
|
|
* RETURNS: TRUE if there is only one provider, otherwise FALSE
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-11-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
#define NET_PROVIDER_ORDER_KEY TEXT("system\\CurrentControlSet\\Control\\NetworkProvider\\Order")
|
|
#define NET_PROVIDER_ORDER_VALUE TEXT("ProviderOrder")
|
|
#define NET_ORDER_SEPARATOR TEXT(',')
|
|
|
|
BOOL
|
|
NoNeedToNotify(
|
|
VOID
|
|
)
|
|
{
|
|
HKEY ProviderKey;
|
|
DWORD Error;
|
|
DWORD ValueType;
|
|
LPTSTR Value;
|
|
BOOL NeedToNotify = TRUE;
|
|
|
|
Error = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE, // hKey
|
|
NET_PROVIDER_ORDER_KEY, // lpSubKey
|
|
0, // Must be 0
|
|
KEY_QUERY_VALUE, // Desired access
|
|
&ProviderKey // Newly Opened Key Handle
|
|
);
|
|
|
|
if (Error != ERROR_SUCCESS) {
|
|
DebugLog((DEB_ERROR, "NoNeedToNotify - failed to open provider key, assuming notification is necessary\n"));
|
|
return(!NeedToNotify);
|
|
}
|
|
|
|
Value = AllocAndRegQueryValueEx(
|
|
ProviderKey, // Key
|
|
NET_PROVIDER_ORDER_VALUE,// Value name
|
|
NULL, // Must be NULL
|
|
&ValueType // Type returned here
|
|
);
|
|
|
|
if (Value != NULL) {
|
|
if (ValueType == REG_SZ) {
|
|
|
|
LPTSTR p = Value;
|
|
while (*p) {
|
|
if (*p == NET_ORDER_SEPARATOR) {
|
|
break;
|
|
}
|
|
p = CharNext(p);
|
|
}
|
|
|
|
if (*p == 0) {
|
|
|
|
//
|
|
// We got to the end without finding a separator
|
|
// Only one provider is installed.
|
|
//
|
|
|
|
if (lstrcmpi(Value, SERVICE_WORKSTATION) == 0) {
|
|
|
|
//
|
|
// it's Lanman, don't notify
|
|
//
|
|
|
|
NeedToNotify = FALSE;
|
|
|
|
|
|
} else {
|
|
|
|
//
|
|
// it isn't Lanman, notify
|
|
//
|
|
|
|
NeedToNotify = TRUE;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
DebugLog((DEB_ERROR, "NoNeedToNotify - provider order key unexpected type: %d, assuming notification is necessary", ValueType));
|
|
}
|
|
|
|
Free(Value);
|
|
|
|
} else {
|
|
DebugLog((DEB_ERROR, "NoNeedToNotify - failed to query provider order value, assuming notification is necessary\n"));
|
|
}
|
|
|
|
Error = RegCloseKey(ProviderKey);
|
|
ASSERT(Error == ERROR_SUCCESS);
|
|
|
|
return(!NeedToNotify);
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************\
|
|
* MprLogonNotify
|
|
*
|
|
* Purpose : Notifies credential managers of a logon.
|
|
*
|
|
* RETURNS: DLG_SUCCESS - the notification went without a hitch
|
|
* DLG_FAILURE - something failed.
|
|
* DLG_INTERRUPTED() - a set of interruptions defined in winlogon.h
|
|
*
|
|
* On DLG_SUCCESS return MprLogonScripts contains a pointer to a
|
|
* Multi-sz string or NULL if there is no data. i.e. multiple concatenated
|
|
* zero terminated strings with a final terminator.
|
|
* The memory should be freed by the caller (if pointer non-NULL) using Free().
|
|
*
|
|
* History:
|
|
* 11-12-92 Davidc Created.
|
|
\***************************************************************************/
|
|
|
|
int
|
|
MprLogonNotify(
|
|
PGLOBALS pGlobals,
|
|
HWND hwndOwner,
|
|
LPTSTR Name,
|
|
LPTSTR Domain,
|
|
LPTSTR Password,
|
|
LPTSTR OldPassword OPTIONAL,
|
|
PLUID LogonId,
|
|
LPWSTR *MprLogonScripts
|
|
)
|
|
{
|
|
int Result;
|
|
NOTIFY_DATA NotifyData;
|
|
|
|
//
|
|
// Check if we really need to bother with this
|
|
//
|
|
|
|
if (NoNeedToNotify()) {
|
|
DebugLog((DEB_TRACE_MPR, "MprLogonNotify - skipping notification - only one provider\n"));
|
|
*MprLogonScripts = NULL;
|
|
return(DLG_SUCCESS);
|
|
}
|
|
|
|
//
|
|
// Set up the environment variables that we will use to pass
|
|
// information to notify process
|
|
//
|
|
|
|
if (!SetCommonNotifyVariables(pGlobals,
|
|
hwndOwner,
|
|
Name,
|
|
Domain,
|
|
Password,
|
|
OldPassword
|
|
)) {
|
|
return(DLG_FAILURE);
|
|
}
|
|
|
|
if (!SetLogonNotifyVariables(LogonId)) {
|
|
return(DLG_FAILURE);
|
|
}
|
|
|
|
|
|
//
|
|
// Initialize our notify data structure
|
|
//
|
|
|
|
NotifyData.pGlobals = pGlobals;
|
|
NotifyData.ReturnBuffer = NULL;
|
|
|
|
//
|
|
// Update windowstation lock so mpnotify can start.
|
|
//
|
|
|
|
UnlockWindowStation(pGlobals->WindowStation.hwinsta);
|
|
FastSetWinstaSecurity( &pGlobals->WindowStation,
|
|
FALSE );
|
|
|
|
|
|
//
|
|
// Create the dialog that will initiate the notify and wait
|
|
// for it to complete
|
|
//
|
|
|
|
Result = WlxDialogBoxParam( pGlobals,
|
|
pGlobals->hInstance,
|
|
(LPTSTR)IDD_CONTROL,
|
|
hwndOwner,
|
|
MprNotifyDlgProc,
|
|
(LONG)&NotifyData);
|
|
|
|
if (Result == DLG_SUCCESS) {
|
|
DebugLog((DEB_TRACE_MPR, "Logon notification return buffer (first string only) = <%ws>\n", NotifyData.ReturnBuffer));
|
|
*MprLogonScripts = NotifyData.ReturnBuffer;
|
|
} else {
|
|
DebugLog((DEB_TRACE_MPR, "Logon notification failed\n"));
|
|
}
|
|
|
|
//
|
|
// Re-lock the windowstation.
|
|
//
|
|
|
|
LockWindowStation(pGlobals->WindowStation.hwinsta);
|
|
|
|
DeleteNotifyVariables();
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************\
|
|
* MprChangePasswordNotify
|
|
*
|
|
* Purpose : Notifies credential managers of a password change
|
|
*
|
|
* RETURNS: DLG_SUCCESS - the notification went without a hitch
|
|
* DLG_FAILURE - something failed.
|
|
* DLG_INTERRUPTED() - a set of interruptions defined in winlogon.h
|
|
*
|
|
* History:
|
|
* 01-12-93 Davidc Created.
|
|
\***************************************************************************/
|
|
|
|
int
|
|
MprChangePasswordNotify(
|
|
PGLOBALS pGlobals,
|
|
HWND hwndOwner,
|
|
PWSTR Provider,
|
|
LPTSTR Name,
|
|
LPTSTR Domain,
|
|
LPTSTR Password,
|
|
LPTSTR OldPassword,
|
|
DWORD ChangeInfo,
|
|
BOOL PassThrough
|
|
)
|
|
{
|
|
int Result;
|
|
NOTIFY_DATA NotifyData;
|
|
|
|
//
|
|
// Check if we really need to bother with this
|
|
//
|
|
|
|
if (NoNeedToNotify()) {
|
|
DebugLog((DEB_TRACE_MPR, "MprChangePasswordNotify - skipping notification - only one provider\n"));
|
|
return(DLG_SUCCESS);
|
|
}
|
|
|
|
//
|
|
// Set up the environment variables that we will use to pass
|
|
// information to notify process
|
|
//
|
|
|
|
if (!SetCommonNotifyVariables(pGlobals,
|
|
hwndOwner,
|
|
Name,
|
|
Domain,
|
|
Password,
|
|
OldPassword
|
|
)) {
|
|
return(DLG_FAILURE);
|
|
}
|
|
|
|
if (!SetChangePasswordNotifyVariables(ChangeInfo,
|
|
PassThrough,
|
|
Provider ) )
|
|
{
|
|
return(DLG_FAILURE);
|
|
}
|
|
|
|
|
|
//
|
|
// Initialize our notify data structure
|
|
//
|
|
|
|
NotifyData.pGlobals = pGlobals;
|
|
NotifyData.ReturnBuffer = NULL;
|
|
|
|
|
|
//
|
|
// Update windowstation security so mpnotify can start.
|
|
//
|
|
|
|
FastSetWinstaSecurity( &pGlobals->WindowStation,
|
|
FALSE );
|
|
|
|
//
|
|
// Create the dialog that will initiate the notify and wait
|
|
// for it to complete
|
|
//
|
|
|
|
//
|
|
// Set timeout to 5 minutes, so the nwcs provider has time to run.
|
|
//
|
|
|
|
WlxSetTimeout( pGlobals, 5 * 60 );
|
|
|
|
Result = WlxDialogBoxParam( pGlobals,
|
|
pGlobals->hInstance,
|
|
(LPTSTR)IDD_CONTROL,
|
|
hwndOwner,
|
|
MprNotifyDlgProc,
|
|
(LONG)&NotifyData);
|
|
//
|
|
// Reset the windowstation security.
|
|
//
|
|
|
|
FastSetWinstaSecurity( &pGlobals->WindowStation,
|
|
TRUE );
|
|
|
|
if (Result == DLG_SUCCESS) {
|
|
Free(NotifyData.ReturnBuffer);
|
|
} else {
|
|
DebugLog((DEB_TRACE_MPR, "Change password notification failed\n"));
|
|
}
|
|
|
|
DeleteNotifyVariables();
|
|
|
|
return(Result);
|
|
}
|