/// Exitlude actions to stop the service, e.g. to remove any state that was created as part of _ServiceStartup. /// /// @param[in] nReason how the service was run (e.g. SERVICE_RUN_INLINE) - different actions may be required /// depending on whether the code is running direct from main() or through another mechanism. static void _ServiceStop (int nReason) { CSettings oSettings; #ifndef _WIN32 if (nReason == SERVICE_RUN_DAEMON) { const TCHAR *pszPID = oSettings.GetPidFile (); if (pszPID) { LOGINFO (TEXT ("Removing PID file ") << pszPID); unlink (pszPID); } } #endif /* ifndef _WIN32 */ }
/// 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 (); }