Ejemplo n.º 1
0
/// Prelude actions to start up the service, e.g. to set any global variables from the settings or perform
/// any system specific actions. E.g. the Windows implementation registers with the service control manager
/// and can optionally set the security descriptor on the process to allow clients to kill/restart it.
///
/// @param[in] nReason how the startup is occuring (e.g. SERVICE_RUN_INLINE) - different actions may be
/// required depending on whether the code is running direct from main() or through another mechansim
static void _ServiceStartup (int nReason) {
	CSettings oSettings;
#ifdef _WIN32
	if (nReason == SERVICE_RUN_SCM) {
		g_hServiceStatus = RegisterServiceCtrlHandler (oSettings.GetServiceName (), ServiceHandler);
	}
	PCTSTR pszSDDL = oSettings.GetServiceSDDL ();
	if (pszSDDL) {
		LOGDEBUG (TEXT ("Setting security descriptor ") << pszSDDL);
		PSECURITY_DESCRIPTOR psdRelative;
		if (ConvertStringSecurityDescriptorToSecurityDescriptor (pszSDDL, SDDL_REVISION_1, &psdRelative, NULL)) {
			DWORD cbAbsolute = 1024;
			PSECURITY_DESCRIPTOR psdAbsolute = (PSECURITY_DESCRIPTOR)malloc (cbAbsolute);
			DWORD cbD = 1024;
			PACL paclD = (PACL)malloc (cbD);
			DWORD cbS = 1024;
			PACL paclS = (PACL)malloc (cbS);
			DWORD cbOwner = 1024;
			PSID psidOwner = (PSID)malloc (cbOwner);
			DWORD cbPGroup = 1024;
			PSID psidPGroup = (PSID)malloc (cbPGroup);
			if (MakeAbsoluteSD (psdRelative, psdAbsolute, &cbAbsolute, paclD, &cbD, paclS, &cbS, psidOwner, &cbOwner, psidPGroup, &cbPGroup)) {
				DWORD dwError = SetSecurityInfo (GetCurrentProcess (), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, paclD, NULL);
				if (dwError == ERROR_SUCCESS) {
					LOGINFO (TEXT ("Security descriptor set on process handle"));
				} else {
					LOGWARN (TEXT ("Couldn't set security descriptor on process handle, error ") << GetLastError ());
				}
			} else {
				LOGWARN (TEXT ("Couldn't create absolute security description, error ") << GetLastError ());
			}
			free (psdAbsolute);
			free (paclD);
			free (paclS);
			free (psidOwner);
			free (psidPGroup);
			LocalFree (psdRelative);
		} else {
			LOGWARN (TEXT ("Couldn't parse SDDL ") << pszSDDL << TEXT (", error ") << GetLastError ());
		}
	} else {
		LOGDEBUG (TEXT ("No security descriptor specified"));
	}
#endif /* ifdef _WIN32 */
	g_lBusyTimeout = oSettings.GetBusyTimeout ();
	_ReportStateStarting ();
}
Ejemplo n.º 2
0
/// Run the service, returning when it has stopped.
///
/// @param[in] nReason how the service is running, e.g. SERVICE_RUN_INLINE, in case actions are different depending
/// on how it was started.
void ServiceRun (int nReason) {
	_ServiceStartup (nReason);
	g_poJVM = CJVM::Create ();
	if (!g_poJVM) {
		LOGERROR (TEXT ("Couldn't create JVM"));
		_ReportStateErrored ();
		return;
	}
	g_poJVM->Start ();
	g_poPipe = CConnectionPipe::Create ();
	if (!g_poPipe) {
		LOGERROR (TEXT ("Couldn't create IPC pipe"));
	}
	while (g_poJVM->IsBusy (g_lBusyTimeout)) {
		_ReportStateStarting ();
	}
	if (g_poPipe && g_poJVM->IsRunning ()) {
		_ReportStateRunning ();
		do {
			LOGDEBUG (TEXT ("Waiting for user connection"));
			ClientConnect *pcc = g_poPipe->ReadMessage ();
			if (pcc) {
				LOGINFO (TEXT ("Connection received from ") << pcc->_userName);
				LOGDEBUG (TEXT ("C++ -> Java = ") << pcc->_CPPToJavaPipe);
				LOGDEBUG (TEXT ("Java -> C++ = ") << pcc->_JavaToCPPPipe);
				// TODO [PLAT-1117] Use challenge/response to verify the user name
				g_poJVM->UserConnection (pcc->_userName, pcc->_CPPToJavaPipe, pcc->_JavaToCPPPipe, pcc->_languageID);
				ClientConnect_free (pcc);
				if (!g_poJVM->IsStopped ()) {
					g_poPipe->CancelLazyClose ();
					if (g_poJVM->IsStopped ()) {
						// Stop might have occurred between the check and the cancel, so restore the cancel
						ServiceStop (false);
					}
				}
				g_oMutex.Enter ();
				if (g_poPipe->IsClosed ()) {
					LOGINFO (TEXT ("Pipe closed with pending connection - reopening"));
					delete g_poPipe;
					g_poPipe = CConnectionPipe::Create ();
					if (g_poPipe) {
						_ReportStateRunning ();
					} else {
						LOGERROR (TEXT ("Couldn't create IPC pipe - shutting down JVM"));
						g_poJVM->Stop ();
					}
				}
				g_oMutex.Leave ();
			} else {
				LOGERROR (TEXT ("Shutting down JVM after failing to read from pipe"));
				g_poJVM->Stop ();
			}
		} while (!g_poJVM->IsBusy (g_lBusyTimeout) && g_poJVM->IsRunning ());
		_ReportStateStopping ();
		while (g_poJVM->IsBusy (g_lBusyTimeout)) {
			_ReportStateStopping ();
		}
		_ReportStateStopped ();
	} else {
		_ReportStateErrored ();
	}
	if (g_poPipe) {
		delete g_poPipe;
		g_poPipe = NULL;
	}
	delete g_poJVM;
	g_poJVM = NULL;
}
Ejemplo n.º 3
0
/// Prelude actions to start up the service, e.g. to set any global variables from the settings or perform
/// any system specific actions. E.g. the Windows implementation registers with the service control manager
/// and can optionally set the security descriptor on the process to allow clients to kill/restart it.
///
/// @param[in] nReason how the startup is occuring (e.g. SERVICE_RUN_INLINE) - different actions may be
/// required depending on whether the code is running direct from main() or through another mechansim
static void _ServiceStartup (int nReason) {
	CSettings oSettings;
#ifdef _WIN32
	if (nReason == SERVICE_RUN_SCM) {
		g_hServiceStatus = RegisterServiceCtrlHandler (oSettings.GetServiceName (), ServiceHandler);
	}
	PCTSTR pszSDDL = oSettings.GetServiceSDDL ();
	if (pszSDDL) {
		LOGDEBUG (TEXT ("Setting security descriptor ") << pszSDDL);
		PSECURITY_DESCRIPTOR psdRelative;
		if (ConvertStringSecurityDescriptorToSecurityDescriptor (pszSDDL, SDDL_REVISION_1, &psdRelative, NULL)) {
			DWORD cbAbsolute = 1024;
			PSECURITY_DESCRIPTOR psdAbsolute = (PSECURITY_DESCRIPTOR)malloc (cbAbsolute);
			DWORD cbD = 1024;
			PACL paclD = (PACL)malloc (cbD);
			DWORD cbS = 1024;
			PACL paclS = (PACL)malloc (cbS);
			DWORD cbOwner = 1024;
			PSID psidOwner = (PSID)malloc (cbOwner);
			DWORD cbPGroup = 1024;
			PSID psidPGroup = (PSID)malloc (cbPGroup);
			if (MakeAbsoluteSD (psdRelative, psdAbsolute, &cbAbsolute, paclD, &cbD, paclS, &cbS, psidOwner, &cbOwner, psidPGroup, &cbPGroup)) {
				DWORD dwError = SetSecurityInfo (GetCurrentProcess (), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, paclD, NULL);
				if (dwError == ERROR_SUCCESS) {
					LOGINFO (TEXT ("Security descriptor set on process handle"));
				} else {
					LOGWARN (TEXT ("Couldn't set security descriptor on process handle, error ") << GetLastError ());
				}
				if (nReason == SERVICE_RUN_SCM) {
					SC_HANDLE hSCM = OpenSCManager (NULL, NULL, GENERIC_READ);
				    if (hSCM) {
						SC_HANDLE hService = OpenService (hSCM, oSettings.GetServiceName (), GENERIC_WRITE | WRITE_DAC);
						if (hService) {
							dwError = SetSecurityInfo (hService, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, NULL, paclD, NULL);
							if (dwError == ERROR_SUCCESS) {
								LOGINFO (TEXT ("Security descriptor set on service"));
							} else {
								LOGWARN (TEXT ("Couldn't set security descriptor on service, error ") << GetLastError ());
							}
							CloseServiceHandle (hService);
						} else {
							LOGWARN (TEXT ("Couldn't open service, error ") << GetLastError ());
						}
						CloseServiceHandle (hSCM);
					} else {
						LOGWARN (TEXT ("Couldn't open SCM, error ") << GetLastError ());
					}
				}
			} else {
				LOGWARN (TEXT ("Couldn't create absolute security description, error ") << GetLastError ());
			}
			free (psdAbsolute);
			free (paclD);
			free (paclS);
			free (psidOwner);
			free (psidPGroup);
			LocalFree (psdRelative);
		} else {
			LOGWARN (TEXT ("Couldn't parse SDDL ") << pszSDDL << TEXT (", error ") << GetLastError ());
		}
	} else {
		LOGDEBUG (TEXT ("No security descriptor specified"));
	}
#else /* ifdef _WIN32 */
	if (nReason == SERVICE_RUN_DAEMON) {
		const TCHAR *pszPID = oSettings.GetPidFile ();
		if (pszPID) {
			LOGINFO (TEXT ("Creating PID file ") << pszPID);
			FILE *f = fopen (pszPID, "wt");
			if (f) {
				fprintf (f, "%d", getpid ());
				fclose (f);
			} else {
				LOGWARN (TEXT ("Couldn't write to PID file ") << pszPID << TEXT (", error ") << GetLastError ());
			}
		} else {
			LOGWARN (TEXT ("No PID file"));
		}
	}
#endif /* ifdef _WIN32 */
	g_lBusyTimeout = oSettings.GetBusyTimeout ();
	_ReportStateStarting ();
}