305 lines
6.9 KiB
C
305 lines
6.9 KiB
C
/*++
|
||
|
||
Copyright (c) 1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
service.c
|
||
|
||
Abstract:
|
||
|
||
part of app that runs as an NT service.
|
||
|
||
Author:
|
||
|
||
Charlie Wickham (charlwi) 03-Oct-1999
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#define UNICODE 1
|
||
#define _UNICODE 1
|
||
|
||
#define LOG_CURRENT_MODULE LOG_MODULE_CLUSPW
|
||
|
||
#include <windows.h>
|
||
#include <winsvc.h>
|
||
#include <stdio.h>
|
||
|
||
#include "clusrtl.h"
|
||
#include "cluspw.h"
|
||
|
||
/* External */
|
||
|
||
/* Static */
|
||
|
||
SERVICE_STATUS ServiceStatus = {
|
||
SERVICE_WIN32_OWN_PROCESS, // dwServiceType
|
||
SERVICE_RUNNING, // dwCurrentState
|
||
0, // dwControlsAccepted
|
||
ERROR_SUCCESS, // dwWin32ExitCode
|
||
ERROR_SUCCESS, // dwServiceSpecificExitCode
|
||
1, // dwCheckPoint
|
||
30000 // dwWaitHint - 30 seconds
|
||
};
|
||
|
||
/* Forward */
|
||
/* End Forward */
|
||
|
||
VOID
|
||
DbgPrint(
|
||
PCHAR FormatString,
|
||
...
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Description
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
{
|
||
CHAR szOutBuffer[1024];
|
||
va_list argList;
|
||
|
||
va_start( argList, FormatString );
|
||
|
||
FormatMessageA(FORMAT_MESSAGE_FROM_STRING,
|
||
FormatString,
|
||
0,
|
||
0,
|
||
szOutBuffer,
|
||
sizeof(szOutBuffer) / sizeof(szOutBuffer[0]),
|
||
&argList);
|
||
|
||
va_end( argList );
|
||
|
||
OutputDebugStringA( szOutBuffer );
|
||
}
|
||
|
||
VOID WINAPI
|
||
ControlHandler(
|
||
DWORD fdwControl // requested control code
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Description
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
{
|
||
DbgPrint("Received service control %1!08X!\n", fdwControl);
|
||
return;
|
||
}
|
||
|
||
VOID WINAPI
|
||
ServiceMain(
|
||
DWORD argc,
|
||
LPTSTR argv[]
|
||
)
|
||
{
|
||
PIPE_RESULT_MSG resultMsg;
|
||
DWORD nodeNameSize = sizeof( NodeName );
|
||
BOOL success;
|
||
DWORD bytesWritten;
|
||
WCHAR cluspwFile[ MAX_PATH ];
|
||
DWORD byteCount;
|
||
DWORD status;
|
||
SERVICE_STATUS_HANDLE statusHandle;
|
||
|
||
//
|
||
// Initialize service to receive service requests by registering the
|
||
// control handler.
|
||
//
|
||
statusHandle = RegisterServiceCtrlHandler( CLUSPW_SERVICE_NAME, ControlHandler );
|
||
if ( statusHandle == NULL ) {
|
||
status = GetLastError();
|
||
DbgPrint("can't get service status handle - %1!u!\n", status);
|
||
return;
|
||
}
|
||
|
||
SetServiceStatus(statusHandle, &ServiceStatus);
|
||
|
||
//
|
||
// parse the args used to start the service
|
||
//
|
||
status = ParseArgs( argc, argv );
|
||
if ( status != ERROR_SUCCESS ) {
|
||
DbgPrint("ParseArgs failed - %1!d!\n", status);
|
||
goto cleanup;
|
||
}
|
||
|
||
//
|
||
// get the node name to stuff in each result msg
|
||
//
|
||
#if (_WIN32_WINNT > 0x04FF)
|
||
success = GetComputerNameEx(ComputerNamePhysicalNetBIOS,
|
||
NodeName,
|
||
&nodeNameSize);
|
||
#else
|
||
success = GetComputerName( NodeName, &nodeNameSize );
|
||
#endif
|
||
if ( !success ) {
|
||
status = GetLastError();
|
||
DbgPrint("GetComputerName failed - %1!d!\n", status );
|
||
status = ERROR_SUCCESS;
|
||
}
|
||
|
||
DbgPrint( "Opening pipe %1!ws!\n", ResultPipeName );
|
||
|
||
//
|
||
// open the named pipe on which to write msgs and final result
|
||
//
|
||
success = WaitNamedPipe( ResultPipeName, NMPWAIT_WAIT_FOREVER );
|
||
if ( success ) {
|
||
PipeHandle = CreateFile(ResultPipeName,
|
||
GENERIC_WRITE,
|
||
0,
|
||
NULL,
|
||
OPEN_EXISTING,
|
||
0,
|
||
NULL);
|
||
if ( PipeHandle == INVALID_HANDLE_VALUE ) {
|
||
status = GetLastError();
|
||
DbgPrint("CreateFile on result pipe failed - %1!d!\n", status );
|
||
}
|
||
}
|
||
else {
|
||
status = GetLastError();
|
||
DbgPrint("WaitNamedPipe on result pipe failed - %1!d!\n", status );
|
||
goto cleanup;
|
||
}
|
||
|
||
//
|
||
// update the password cache
|
||
//
|
||
wcscpy( resultMsg.NodeName, NodeName );
|
||
resultMsg.MsgType = MsgTypeFinalStatus;
|
||
resultMsg.Status = ChangeCachedPassword(UserName,
|
||
DomainName,
|
||
NewPassword);
|
||
|
||
if ( resultMsg.Status == ERROR_SUCCESS ) {
|
||
ClRtlLogPrint(LOG_NOISE,
|
||
"[CPW] Cluster service account password successfully updated.\n");
|
||
CL_LOGCLUSINFO( SERVICE_PASSWORD_CHANGE_SUCCESS );
|
||
} else {
|
||
ClRtlLogPrint(LOG_CRITICAL,
|
||
"[CPW] Cluster service account password update failed - %u.\n",
|
||
status);
|
||
|
||
ClusterLogEvent0(LOG_CRITICAL,
|
||
LOG_CURRENT_MODULE,
|
||
__FILE__,
|
||
__LINE__,
|
||
SERVICE_PASSWORD_CHANGE_FAILED,
|
||
sizeof( resultMsg.Status ),
|
||
(PVOID)&resultMsg.Status);
|
||
}
|
||
|
||
DbgPrint("Final Result: %1!d!\n", resultMsg.Status );
|
||
|
||
success = WriteFile(PipeHandle,
|
||
&resultMsg,
|
||
sizeof( resultMsg ),
|
||
&bytesWritten,
|
||
NULL);
|
||
if ( !success ) {
|
||
DbgPrint("WriteFile failed in wmain - %1!d!\n", GetLastError() );
|
||
DbgPrint("final status: %1!d!\n", resultMsg.Status);
|
||
}
|
||
|
||
CloseHandle( PipeHandle );
|
||
|
||
//
|
||
// let SCM know we're shutting down
|
||
//
|
||
cleanup:
|
||
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||
ServiceStatus.dwWin32ExitCode = status;
|
||
SetServiceStatus(statusHandle, &ServiceStatus);
|
||
|
||
} // ServiceMain
|
||
|
||
VOID
|
||
ServiceStartup(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Description
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
{
|
||
SERVICE_TABLE_ENTRY dispatchTable[] = {
|
||
{ CLUSPW_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
|
||
{ NULL, NULL }
|
||
};
|
||
DWORD status;
|
||
DWORD logLevel = 0;
|
||
|
||
status = ClRtlInitialize( FALSE, &logLevel );
|
||
if ( status != ERROR_SUCCESS ) {
|
||
DbgPrint("Couldn't initialize cluster RTL - %d\n", status );
|
||
} else {
|
||
ClRtlLogPrint(LOG_NOISE,
|
||
"[CPW] Initiating cluster service account password update\n");
|
||
}
|
||
|
||
CL_LOGCLUSINFO( SERVICE_PASSWORD_CHANGE_INITIATED );
|
||
|
||
//
|
||
// this part runs on the cluster nodes; validate that we're really
|
||
// running in the correct environment
|
||
//
|
||
#if 0
|
||
byteCount = GetModuleFileName( NULL, cluspwFile, sizeof( cluspwFile ));
|
||
if ( wcsstr( cluspwFile, L"admin$" ) == NULL ) {
|
||
DbgPrint("-z is not a valid option\n");
|
||
return ERROR_INVALID_PARAMETER;
|
||
}
|
||
#endif
|
||
|
||
if ( !StartServiceCtrlDispatcher(dispatchTable)) {
|
||
status = GetLastError();
|
||
DbgPrint("StartServiceCtrlDispatcher failed - %1!d!\n", status);
|
||
}
|
||
|
||
} // ServiceMain
|
||
|
||
/* end service.c */
|